Promise.all с array.map работает параллельно - PullRequest
0 голосов
/ 03 августа 2020

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

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

 // Adapt every image in the album to its dimensions
    await Promise.all(
      album.map(async (image) => {
        const adaptedImage = await adaptImageToAlbum(image);
        // Add the photo to the final album
        finalAlbum[image.index] = adaptedImage;
      })
    );

Дело в том, что если вместо этого я использую этот код

 // Adapt every image in the album to its dimensions
    await Promise.all(
      album.map(async (image) => {
        const adaptedImage = await adaptImageToAlbum(image);
        // Add the photo to the final album
        finalAlbum.push(adaptedImage);
      })
    );

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

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Вы можете отсортировать массив перед обработкой элементов

const finalAlbum = await Promise.all(
  album
    .sort((a, b) => a.index - b.index)
    .map((image) => adaptImageToAlbum(image));
);

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

1 голос
/ 05 августа 2020

Я бы использовал BlueBird Promise.each , через который итерация будет выполняться последовательно, ожидая каких-либо обещаний в процессе:

const BlueBird = require("bluebird");

await BlueBird.each(album, async function(image) {
  const adaptedImage = await await adaptImageToAlbum(image);
  finalAlbum.push(adaptedImage);
})

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

const album = [1,2,3,4,5];

async function test(album) {
  let finalAlbum = [];
await Promise.all(
  album.map(async (image) => {
    const adaptedImage = await new Promise((resolve) => {
      setTimeout(() => {
        resolve(image);
      }, Math.random() * 100);
    });
    finalAlbum.push(adaptedImage);
  })
)
console.log(finalAlbum);  //random order
}

Тогда как с Bluebird он всегда будет сохранять исходный порядок:

const BlueBird = require("bluebird");

const album = [1,2,3,4,5];

async function test2(album) {
  let finalAlbum = [];
  await BlueBird.each(album, async function(image) {
      const adaptedImage = await new Promise((resolve) => {
        setTimeout(() => {
          resolve(image);
        }, Math.random() * 100);
      });
      finalAlbum.push(adaptedImage);
    }
  )
  console.log(finalAlbum); // [1,2,3,4,5], keeps array order
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...