Mordern Javascript: Использование функции Async-Await.


Введение

В современном JavaScript есть такие возможности, как Promises, стрелочные функции и т.д. Ни одна из них, на мой взгляд, не является большим улучшением языка, чем Async-Await. Async-Await упрощает работу с нашим кодом на основе обещаний, который выглядит скорее синхронным, чем асинхронным.

В этой статье мы подробно рассмотрим, как работают функции Async, их преимущества и практические примеры использования.

Что такое Async-Await?

Async Await — это просто небольшой набор инструментов, облегчающих работу с обещаниями. Он позволяет непрерывно использовать методы обещаний и помогает нам лучше управлять множеством асинхронных действий при создании наших приложений.

Предварительные условия

  • Как пользоваться командной строкой/терминалом.

  • Базовое понимание обещаний Javascript.

  • Написание стрелочных функций.

  • Использование setTimeout().

  • Установлен Node.

Начало работы

Мы начнем с создания каталога, содержащего наш файл JavaScript. Вы можете перейти в терминал и набрать следующее:

mkdir async
Войти в полноэкранный режим Выйти из полноэкранного режима

Чтобы изменить каталог на async, введите следующий код:

cd async
Войти в полноэкранный режим Выйти из полноэкранного режима

Чтобы создать новый файл Javascript под названием «async-await.js» с переменной внутри, введите код ниже:

echo var msg > async-await.js
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь мы можем открыть нашу директорию в visual studio code с помощью команды ниже:

code . 
Enter fullscreen mode Выйти из полноэкранного режима

Функции и Async-функции (чем они отличаются)

Чтобы действительно понять, чем функции отличаются от Async-функций, давайте создадим стрелочную функцию под названием ‘doWork’. Эта функция будет пустой, и мы будем записывать ее результат в консоль, используя приведенный ниже код:

let doWork = () => {
};
console.log(doWork())
Вход в полноэкранный режим Выйти из полноэкранного режима

При запуске нашего файла async-await.js на терминале будет выведено неопределенное значение, потому что функции обычно ожидают возврата значения. Чтобы запустить наш файл, откройте командную строку и введите:

node async-await
Войти в полноэкранный режим Выйти из полноэкранного режима


Чтобы сделать нашу функцию асинхронной, достаточно пометить ее как асинхронную непосредственно перед объявлением функции. т.е.

let doWork = async () => {
};
console.log(doWork())
Войти в полноэкранный режим Выйти из полноэкранного режима

Этим небольшим изменением кода мы уже меняем поведение нашей программы. Мы больше не будем видеть неопределенную печать в терминале. Чтобы убедиться в этом, нам нужно запустить наш файл еще раз, используя:

node async-await
Войти в полноэкранный режим Выйти из полноэкранного режима


В этом случае мы получим обещание, которое было выполнено со значением undefined.

Это первое, что нужно отметить об асинхронных функциях: асинхронные функции всегда возвращают обещание. Это обещание выполняется со значением, которое вы решили вернуть из функции. В настоящее время мы ничего не возвращаем, поэтому обещание выполняется с неопределенным значением.

Теперь давайте явно вернем значение из функции async. Для этого вернем строку, содержащую мое имя.

let doWork = async () => {
   return "Emmanuel"
};
console.log(doWork())
Вход в полноэкранный режим Выход из полноэкранного режима

Следует отметить, что возвращаемое значение из doWork() — это не «Эммануил», это все еще Promise, которое было выполнено со строкой «Эммануил». Когда мы запускаем наш код, мы видим, что это значит.

Использование .then() и .catch()

Мы не делаем многого, просто регистрируя возвращаемое значение, давайте посмотрим, как использовать метод .then() для запуска некоторого кода при выполнении функции async.

Для этого нам просто нужно использовать метод .then() в нашей функции doWork. В качестве примера, мы просто занесем в журнал результат ее встроенной функции arrow. Которая содержит возвращаемое значение асинхронной функции

let doWork = async () => {
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот result для этого:

Мы также можем настроить вызов .catch(), который представляет собой просто функцию, получающую ошибку. Давайте подключим его к нашему методу .then() с помощью приведенного ниже кода:

let doWork = async () => {
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
Вход в полноэкранный режим Выход из полноэкранного режима

Только одна небольшая проблема, когда мы запускаем наш файл, мы все еще получаем результат «Emmanuel».

Итак, как же нам заставить .catch() работать?
Если мы выбросим ошибку из нашей асинхронной функции, это будет то же самое, что отклонить обещание, отправленное обратно из асинхронной функции.
Чтобы выбросить ошибку, измените свой код на приведенный ниже:

let doWork = async () => {
   throw New Error("Something went wrong")
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
Войти в полноэкранный режим Выйти из полноэкранного режима

На этот раз при выполнении нашего кода мы получим строку «e», а также весь объект ошибки.

Использование оператора Await

До сих пор мы рассматривали базовую структуру асинхронных функций. Теперь нам предстоит изучить вторую половину асинхронных функций —Await функцию.
Оператор await можно использовать только в асинхронных функциях, а поскольку вся суть асинхронного await заключается в том, чтобы упростить работу с кодом, основанным на обещаниях.

Чтобы оживить ситуацию, давайте создадим код на основе обещания, это будет просто обещание, которое складывает два числа через две секунды, вот код для этого:

const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 2000)
    })
}

let doWork = async () => {
   throw New Error("Something went wrong")
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})

Войти в полноэкранный режим Выйти из полноэкранного режима

Если бы мы использовали цепочку обещаний, код потребовал бы вызовов .then() и функций обратного вызова, просто чтобы получить значение add().

Async-Await устраняет этот монотонный способ выполнения задач.

То, к чему мы получаем доступ внутри нашей async-функции, — это оператор await. Оператор await работает с обещаниями. И поскольку у нас уже есть обещание под названием add, мы будем использовать его с оператором await. Мы собираемся сложить два числа вместе, а затем ожидать результата обещания add, который мы сохраним в нашей переменной под названием «sum», а затем вернем значение «sum».

const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 2000)
    })
}

let doWork = async () => {
   const sum = await add(1, 99);
   return sum
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Когда мы снова запустим наш файл async-await.js, мы получим результат, показанный ниже.

Выполнение нескольких задач с помощью Async-Await

Замечательно, мы впервые использовали await в нашем приложении. Мы можем пойти еще дальше, выполняя другие задачи на основе обещаний в нашей функции async.

Я буду делать больше вызовов add(), используя значение предыдущих сумм. Вот код для этого

const doWork = async () => {
   const sum =  await add(1, 99)
   const sum2 = await add(sum, 50)
   const sum3 = await add(sum2, 3)
   return sum3
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Это сделает несколько обращений к sum, и нам придется ждать 2 секунды, пока каждое обещание будет выполнено. Это говорит нам о том, что async-await не обязательно делает все быстрее, он просто упрощает работу. После 6 секунд ожидания мы получим конечный результат 153

Одно из преимуществ, которое дает нам Async-Await, — это возможность поместить все вызовы обещаний в одну область видимости. Это делает код более читабельным и синхронным.

Теперь осталось завершить работу, написав код обработки ошибок, когда наши обещания будут отклонены. Мы добавим оператор if, который поможет нам проверить, являются ли числа, складываемые функцией sum(), отрицательными. Мы вернем код отклонения, чтобы он завершил работу и отклонил обещание, если это условие выполнено.

Давайте улучшим нашу функцию add(), добавив оператор if.

const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (a < 0 || b < 0) {
                return reject('Numbers must be non-negative')
            }

            resolve(a + b)
        }, 2000)
    })
}
Вход в полноэкранный режим Выход из полноэкранного режима

Если мы запустим наш файл async-await после добавления этого оператора, мы получим тот же результат, но когда мы внесем некоторые изменения в числа в add(), мы получим ошибку: Вот код и изображение для этого ниже:

const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (a < 0 || b < 0) {
                return reject('Numbers must be non-negative')
            }

            resolve(a + b)
        }, 2000)
    })
}

const doWork = async () => {
    const sum = await add(1, -99)
    const sum2 = await add(sum, 50)
    const sum3 = await add(sum2, -3)
    return sum3
}

doWork().then((result) => {
    console.log('result', result)
}).catch((e) => {
    console.log('e', e)
})
Вход в полноэкранный режим Выход из полноэкранного режима

Выход:


Вывод будет зарегистрирован после того, как мы подождем начальные 2 секунды, которые указаны в нашей функции setTimeout().

Заключение

Итак, мы рассмотрели, чем async await отличается от функций, оператор await и как выполнять несколько задач с помощью async-await. Мы также узнали, что async-await дает нам одну область для размещения наших обещаний.

Я надеюсь, что эта статья была полезной, пожалуйста, оставьте комментарий и следите за мной, чтобы получать больше материалов.

Оцените статью
devanswers.ru
Добавить комментарий