Что такое обещания в JavaScript? Как они работают? Это один из распространенных вопросов, которые задают для позиций JavaScript. Кто-то спросил меня об этом, и я не мог четко сформулировать это. Итак, я решил взять на себя ответственность написать об этом в блоге и подробно разобраться в концепции. Простое определение Promise состоит в том, что это заполнитель для значения, которое будет разрешено когда-нибудь в будущем. Он может находиться в любом из этих трех состояний: ожидающий, выполненный или отклоненный.

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

  1. Паста пенне
  2. Брокколи
  3. Красный соус
  4. Сыр моцарелла

Для завершения блюда мне необходимо:

  1. Отварить макароны в воде (5 минут)
  2. Нарезать брокколи кусочками среднего размера (3 мин.)
  3. Разогрейте духовку до 400 градусов по Фаренгейту (3 минуты).
  4. Выложите отварную пасту в прямоугольную стеклянную сковороду (1 мин).
  5. Выложить слой красного соуса, брокколи и сыра (1 мин)
  6. После того, как духовка будет предварительно нагрета, поместите форму для макарон в духовку (1 мин).
  7. Паста готова к подаче через 15 минут (15 минут).

Прежде чем делать макароны на JavaScript, давайте разберемся, как JavaScript выполняет код. Он будет выполнять код синхронно. Мы знаем, что нужно 5 минут, чтобы сварить макароны, 3 минуты, чтобы разрезать брокколи, и разогреть духовку ... Чтобы смоделировать это, мы должны установить задержку после начала каждой операции. Мы можем сделать это, используя функцию JavaScript setTimeout и передав величину задержки в миллисекундах. Для простоты в этом примере мы будем считать, что 1 миллисекунда = 1 минута.

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

Предполагая, что мы уже написали функции для выполнения этих шагов, «код изготовления макаронных изделий» можно было бы написать очень лаконично, используя Bluebird, библиотеку обещаний javascript. Функция карты Bluebird позволяет нам выполнять вызовы обещаний в массиве и только после того, как все они разрешены, возвращает результат в формате массива. Функция карты будет запускать все операции одновременно, параллельно, и в зависимости от того, когда все они будут разрешены, она вернет результат. В приведенном ниже примере я использую mapSeries вместо map, потому что при приготовлении макаронных изделий я не могу одновременно выполнять определенные операции, такие как кипячение макаронных изделий и их укладывание на сковороду. Поэтому я решил выполнять все операции последовательно, используя mapSeries от bluebird, чтобы итеративно выполнять каждый шаг по одному.

Мы также можем сделать то же самое с функцией map, если присвоим ее свойству concurrency значение 1. Единственная разница в том, что mapSeries будет выполнять каждую операцию последовательно, тогда как map с concurrency, равным 1, выберет любую операцию случайным образом. Оба будут выполнять только одну операцию за раз. При использовании этого метода время, необходимое для приготовления макаронных изделий, составляет 29 минут (все время складывается для каждого шага в серии).

В приведенном выше методе мы выполняем только один шаг за раз, то есть запускаем следующую задачу только после завершения предыдущей. Мы можем сократить время, необходимое для приготовления макарон, выполнив некоторые из начальных шагов параллельно, например, начав шаги 1,2 и 3 одновременно. Только после того, как они будут выполнены, мы сможем выполнить остальные шаги по порядку. Давайте посмотрим, как управлять каждым этапом, чтобы эффективно готовить макароны.

В приведенном выше коде я использую «карту» для запуска начальных шагов, которые могут выполняться параллельно (строка 68). После завершения всех начальных шагов я использую «mapSeries» для последовательного выполнения остальных шагов (строка 75). Я также печатаю время, необходимое для запуска первого набора событий и следующего набора событий. Время на приготовление пасты таким способом составит всего 23 минуты (шаги 1,2,3 параллельно). После выполнения шагов 1, 2 и 3 выполните остальные шаги в серии. Теперь паста готова к подаче на тарелку. Я сейчас пойду съесть пасту. А пока, я надеюсь, вы поняли, что такое карта bluebird и mapSeries.