В этом посте мы узнаем, как мы можем упростить приложение NodeJS на основе обратного вызова или обещания с помощью async/await. Если вы хотите прочитать про обещания в NodeJS, пожалуйста, прочтите мой предыдущий пост здесь.
Что такое асинхронные функции в NodeJS?
Асинхронная функция изначально доступна в NodeJS и объявлена с помощью ключевого слова async. Асинхронные всегда возвращают обещание, даже если вы явно не прописываете их для этого. Кроме того, на данный момент ключевое слово await доступно только внутри асинхронных функций — его нельзя использовать в глобальной области видимости.
В чем преимущества async/await
- Это позволяет нам использовать ключевое слово await внутри асинхронной функции. Без асинхронного ключевого слова await это рассматривается как ошибка
- Это позволяет асинхронным функциям возвращать обещание
Пример функции Promise/async/await/Normal JS. Все нижеприведенные три функции a, b, c идентичны
/** * @returns {Promise<string>} */ function a() { return Promise.resolve('a'); } async function b() { return Promise.resolve('b'); } async function c() { return 'c'; } console.log(a()); console.log(b()); console.log(c());
Разница между async/await и Promise
В обещании мы должны написать .then с функцией обратного вызова, но в асинхронном ожидании мы можем просто избавиться от функций .then (.then заменяется ожиданием).
let run = async () => { // Promise version of code read('../dir/file1.txt') .then(data => { console.log(data.toString()); }).catch(err => { console.log(err) }) // Async/Await version const data = await read('../dir/file1.txt'); console.log(data.toString()); // Async-Await version of reading multiple files const [data1, data2, data3] = await Promise.all([ read('../dir/file1.txt'), read('../dir/file2.txt'), read('../dir/file3.txt') ]) console.log(data1.toString()); console.log(data2.toString()); console.log(data3.toString()); } run()
Когда мы используем async/await, нам редко требуется .then, потому что await обрабатывает наше ожидание.
Обработка ошибок в асинхронном ожидании
Если обещание разрешается нормально, то await promise возвращает результат. Но в случае отклонения он выдает ошибку, как если бы в этой строке был оператор throw. Ниже фрагмент кода и
async function getData() { return Promise.reject(new Error("New Error!")); }
этот фрагмент кода идентичен
async function getData() { return new Error("New Error!"); }
Мы можем поймать эту ошибку, используя try..catch, так же, как и обычный бросок. В случае ошибки управление переходит к блоку catch.
async function getData() { try { let response = await fetch('http://someurl'); } catch (err) { // Error! alert(err); } } getData();
Если у нас нет try..catch, то обещание, сгенерированное вызовом асинхронной функции f(), будет отклонено. Мы можем добавить .catch для обработки:
async function getData() { let response = await fetch('http://someurl'); } // getData() becomes a rejected promise getData().catch(alert); // Error!
Если мы забудем добавить туда .catch, то получим необработанную ошибку промиса (видимую в консоли). Мы можем поймать такие ошибки, используя глобальный обработчик события unhandledrejection.
Это все, чем я могу поделиться в async/await. Если у вас есть больше пунктов, чтобы поделиться, пожалуйста, прокомментируйте ниже. Это поможет мне и другим получить больше знаний об async/await. Спасибо за прочтение. Пожалуйста, подпишитесь на поддержку и другие материалы, подобные этому.
Вам понравилась эта статья? Если да, то получите больше похожего контента, подписавшись на Decoded, наш канал на YouTube!
Примечание. Более интересный контент также доступен на https://ajaykrp.me. Пожалуйста, проверьте это.