Пакетная обработка промисов

Пакетная обработка промисов

Одновременное выполнение кода

Чтобы ускорить выполнение, мы обычно выполняем код параллельно.
Одним из способов одновременного выполнения кода в JavaScript является одновременный вызов множества обещаний без ожидания их результатов, затем вы используете Promise.all для ожидания завершения всех обещаний. Посмотрите пример ниже:

const promiseA = asyncFnA();
const promiseB = asyncFnB();

const results = await Promise.all([promiseA, promiseB]);

Приведенный выше код будет выполнять asyncFnA и asyncFnB одновременно, а Promise.all будет ожидать выполнения обоих обещаний для разрешения.

Одновременное выполнение многих обещаний

Давайте посмотрим на этот код

const users = await User.find(); // return all users in the database

const results = await Promise.all(users.map(async (user) => processUser(user));

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

Пакетная обработка обещаний

export async function processPromisesBatch(
  items: Array<any>,
  limit: number,
  fn: (item: any) => Promise<any>,
): Promise<any> {
  let results = [];
  for (let start = 0; start < items.length; start += limit) {
    const end = start + limit > items.length ? items.length : start + limit;

    const slicedResults = await Promise.all(items.slice(start, end).map(fn));

    results = [
      ...results,
      ...slicedResults,
    ]
  }

  return results;
}

Usage

const results = await processPromisesBatch(users, 100, processUser)

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

В заключение

Понимание ограничений вашего языка программирования и среды выполнения может помочь вам разработать решение для их обхода.

Поделитесь решениями, которые вы разработали на основе ограничений вашего языка программирования, среды выполнения или фреймворка.