Из прочитанного про 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()?
Ответ
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 код в то, что уже сегодня можно запустить в большинстве браузеров.
Комментариев нет:
Отправить комментарий