В этом посте мы узнаем, как мы можем упростить приложение NodeJS на основе обратного вызова или обещания с помощью async/await. Если вы хотите прочитать про обещания в NodeJS, пожалуйста, прочтите мой предыдущий пост здесь.

Что такое асинхронные функции в NodeJS?

Асинхронная функция изначально доступна в NodeJS и объявлена ​​с помощью ключевого слова async. Асинхронные всегда возвращают обещание, даже если вы явно не прописываете их для этого. Кроме того, на данный момент ключевое слово await доступно только внутри асинхронных функций — его нельзя использовать в глобальной области видимости.

В чем преимущества async/await

  1. Это позволяет нам использовать ключевое слово await внутри асинхронной функции. Без асинхронного ключевого слова await это рассматривается как ошибка
  2. Это позволяет асинхронным функциям возвращать обещание

Пример функции 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. Пожалуйста, проверьте это.