Понимание промисов в JavaScript

Понимание промисов в JavaScript

7 марта 2023 г.

Всем привет!

На написание этой статьи меня вдохновили мои ученики и подопечные. Подобных статей много в интернете, но эту я посвящаю новичкам (конкретно тем, кому нужно знать только основы).

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

ВАЖНО. Это неполное руководство по асинхронным функциям и обещаниям. Если вы хотите узнать больше, лучше ознакомьтесь с веб-документами mdn.

Что обещают?

Говоря технически, Promise — это объект. Он представляет возможное завершение (или сбой) асинхронной операции и ее результирующее значение.

Лучшим примером объекта Promise является запрос HTTP:

Sending an HTTP request in Postman

Когда вы отправляете запрос - серверу требуется некоторое время для его обработки (это означает, что мы не получаем ответ от сервера сразу).

Server responded to the request

Как только сервер обработал запрос — мы получаем от него ответ. Как видно на снимке экрана, ответ сервера занял ~3 секунды.

КАК это работает в Javascript?

Итак, если бы мы выполнили функцию JavaScript fetch, чтобы получить ответ — мы также не получим его сразу.

То есть функция fetch вернет Promise вместо ответа:

fetch function returned a Promise

С точки зрения JavaScript — он выполнил свою работу (запрос отправлен, не так ли?).

Если мы посмотрим на функцию fetch, мы увидим, что это функция, которая возвращает Promise<Response>:

fetch function type declaration

Это означает, что эта функция возвращает Promise (конечно же). Но если мы подождем разрешения Promise, он вернет объект Response!

Как мы ждем? Ну, есть 2 способа сделать это…

Синхронный код

Используйте функцию затем:

fetch and following then function

Функция затем получает разрешенный объект (Response в текущем примере) — то есть все, что Promise<something> попало внутрь <> ;.

Асинхронный код

Использовать async / await:

await expression in async function

Чем это отличается от того, что мы сделали в примере с синхронным (синхронным)?

  1. Вам не нужна функция .then() для извлечения значения из функции async (fetch).

2. Ключевое слово await доступно в функциях async только.

3. Если вы не будете использовать слово await в асинхронных функциях (тех, которые возвращают объекты Promise) - они будут выполняться одновременно.

Асинхронный запуск кода

Синтаксис

async / await и then() кажется излишним в большинстве случаев использования, если вы тот, кто разрабатывает автоматизированные тесты. . Почему этот синтаксис вообще существует? Какой в ​​этом смысл? Почему мы не можем просто получить нужное нам значение из функции?

Ответ прост — это позволяет нам определять функции без строгой последовательности команд.

То есть, что если нам нужно выполнить 10 запросов, но не обязательно выполнять их синхронно (один за другим)?

Promise.all([
  fetch(...),
  fetch(...),
  ...
]).then((responses) => {
    responses.forEach(value => console.log(value))
  })

Приведенный выше код будет запускать все команды fetch внутри Promise.all([]), а затем ждать их разрешения (завершения) и регистрировать в консоли каждый ответ.

ИЛИ вы можете сделать то же самое с конструкцией async/await:

const [responses] = await Promise.all([
  fetch(...),
  fetch(...),
  ...
])

responses.forEach(value => console.log(value))

Заключение

Теперь вы знаете основы использования объекта Promise, и этого будет достаточно для большинства случаев использования, особенно если вы работаете с автоматическими тестами.

Кроме того, имейте в виду, что большинство разработчиков используют конструкцию async / await вместо sync (т. е. .then()), поскольку он должен быть «синтаксическим сахаром».

Спасибо за прочтение! Надеюсь, вы сегодня узнали что-то новое :nerd_face:


Оригинал