Страницы

Поиск по вопросам

понедельник, 30 декабря 2019 г.

Правильное использование async/await

#javascript #nodejs #async_await


Из прочитанного про async/await, я понял что эта конструкция должна упростить код,
избавить разработчиков от лишних коллбэков. Я запустил такой пример:

var request = require('request');
var async = require('asyncawait/async');
var await = require('asyncawait/await');

function getQuote() {
  var quote;

  return new Promise(function(resolve, reject) {
    request('http://ron-swanson-quotes.herokuapp.com/v2/quotes', function(error,
response, body) {
      quote = body;
      resolve(quote);
    });
  });
}

var main = async (()=>{
  var quote = await(getQuote());
  console.log(quote);
});


main();

console.log('Ron once said,');


В консоли вижу следующее:

Ron once said,
["Great job, everyone..."]


Это говорит о том, что main() срабатывает после console.log('Ron once said,').

Но в чем суть тогда, если один-черт нужно передавать коллбэк в main() чтобы сначала
получить результат запроса, а потом что-то с ним делать?

Как добиться того, чтобы в данном примере сначала сработал main() а потом console.log()?
    


Ответы

Ответ 1



async определяет, что функция является асинхронной и позволяет использовать внутри нее оператор await, который приостанавливает выполнение функции, на время получения результата. Обращаю ваше внимание, что конструкцию await можно использовать не везде, а только внутри асинхронных функций. До определения async/await подобно поведение достигалось использованием генераторов в комплекте с библиотеками, вроде co. Я уже детально расписывал этот подход в одном из своих ответов. Теперь несколько слов о вашем конкретном примере. Основная цель, насколько я могу видеть, в псевдо-синхронном выполнении связки: main(); console.log('Ron once said,'); Казалось бы, функция main определена как асинхронная и этот блок должен выполняться последовательно. Однако вы упускаете один очень важный момент: определение функции асинхронной не делает ее вызов псевдо-синхронным автоматически. Вам нужно в явном виде дождаться результата выполнения main. Для этого нужно просто обернуть весь ваш код в IIFE-выражение, использующее асинхронную функцию и дождаться результата выполнения main: let getData = () => { return new Promise(function(resolve, reject) { setTimeout(() => { resolve('Great job, everyone...'); }, 500); }); }; (async () => { let main = async ()=> { console.log(await getData()); }; await main(); console.log('Ron once said,'); })(); Этот пример выведет: Great job, everyone... Ron once said, А вот и работающий пример на JSFiddle. Замечание: Код выше я написал на чистом JS, без использования библиотеки-полифила asyncawait. Если вы хотите использовать эту библиотеку, то вместо ключевых слов async/await вам нужно в явном виде вызывать функции этой библиотеки. В качестве альтернативы, я бы предложил использовать Babel, превращающий ES 6/7 код в то, что уже сегодня можно запустить в большинстве браузеров.

Ответ 2



main(); Если надо ждать, то это надо указать: await (main());

Комментариев нет:

Отправить комментарий