В массиве 100 обещаний, и нам нужно обрабатывать 5 одновременно за JS. как этого добиться? - PullRequest
0 голосов
/ 17 февраля 2020

В массиве 100 обещаний, и нам нужно обрабатывать 5 одновременно в JS. как этого добиться? (Спросил в интервью Microsoft)

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Используйте бассейн. В JS имеется ряд реализаций, таких как эта , которая имеет красивый API:

const PromisePool = require("async-promise-pool");

// concurrency is the only option for PromisePool and enables you to 
// choose how many promises will run at once
const pool = new PromisePool({ concurrency: 3 });

// elsewhere add functions to the pool that produce promises. We use
// functions here to prevent the promises from immediately executing.
pool.add(() => thingThatReturnsAPromise());

// you can await pool.all to ensure that all promises in the pool are 
// resolved before continuing.
await pool.all();
0 голосов
/ 17 февраля 2020

Я бы использовал функцию для выполнения обещаний в последовательности, а не параллельно. После этого создайте массив из 5 групп для параллельного решения, используя Promise.all:

const PROMISES_AMOUNT = 100
const GROUP_AMOUNT = 5
 
 // Function to divide the array in various chuncks of similar size
 function chunkArray(myArray, chunk_size){
    let index = 0;
    let arrayLength = myArray.length;
    let tempArray = [];
    
    for (index = 0; index < arrayLength; index += chunk_size) {
        myChunk = myArray.slice(index, index+chunk_size);
        // Do something if you want with the group
        tempArray.push(myChunk);
    }

    return tempArray;
}
 
 // the promise we will use
 function interval(index) {
    return new Promise(function(resolve, reject) {
        const time = index*100
        setTimeout(function() {
        		console.log(`Waited ${time}!`)
           	resolve(index);
        }, time)
  })
};

// Our array of 100 promises
const promises = new Array(PROMISES_AMOUNT).fill(null).map((_, index) => interval(index ))

// The array of 100 promises divided by groups of 5 elements
const groupedPromises = chunkArray(promises, GROUP_AMOUNT).map((promisesGroup) => () => Promise.all(promisesGroup))

// A function to divide an array
function chunkArray(myArray, chunk_size){
    var index = 0;
    var arrayLength = myArray.length;
    var tempArray = [];
    
    for (index = 0; index < arrayLength; index += chunk_size) {
        myChunk = myArray.slice(index, index+chunk_size);
        // Do something if you want with the group
        tempArray.push(myChunk);
    }

    return tempArray;
}

// A function to execute promises in sequence
const promisesInSequence = (arrayOfTasks) => {
  let results = []
  return new Promise((resolve, reject) => {
    const resolveNext = (arrayOfTasks) => {
      // If all tasks are already resolved, return the final array of results
      if (arrayOfTasks.length === 0) return resolve(results)

      // Extract first promise and solve it
      const first = arrayOfTasks.shift()

      first().then((res) => {
        console.log('Solved a group in parallel: ', res)
        results.push(res)
        resolveNext(arrayOfTasks)
      }).catch((err) => {
        reject(err)
      })
    }
    resolveNext(arrayOfTasks)
  })
}

promisesInSequence(groupedPromises)
	.then((result) => console.log(result))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...