Promise.all () ведут себя очень странно в Node - PullRequest
0 голосов
/ 24 января 2019

Я обнаружил очень странную ошибку при использовании Promises в NodeJS.У меня есть массив, который содержит массив обещаний.

Пример:

пусть обещания = [[P1, P2, P3], [P4, P5], [P6], [P7, P8], [P9, P10, P11, P12, P13]]

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

(async () => {
  for(let i = 0; i < promises.length; i++) {
    console.log('Starting', i + 1, ' of ', promises.length, ' Total:',promises[i].length);
    await Promise.all(promises[i]).then(() => {
      console.log('Finished Section ', i + 1);
    }).catch(err => {
      console.log(err.message);
    })
    console.log('Next Set of promises');
  }
  fs.appendFileSync('links.json', JSON.stringify(json));
})()

Но это не так.Фактически выполняется следующее:

Шаг 1 : Первая итерация начинается

Шаг 2 : Все обещания в массиве обещаний выполняются

Шаг 3 : Как только все обещания разрешены, цикл переходит к следующей итерации.

Ожидаемый результат: Разрешение первого набора обещаний -> итерация -> второй наборобещаний -> повторение и т. д.

Я что-то упустил или узел выполняет Обещания по-другому?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Сохраните в массиве функции, использованные для создания вашего обещания (не * фактическое само обещание).

Затем выполните итерацию каждого, вызовите функцию, которая создаст ваше обещание (изапустите его) и дождитесь завершения этой партии.Как только пакет завершен, переходите к следующему.

//function to create a promise
function p(id){
  return new Promise((resolve,reject)=>{
    setTimeout(function(){
      resolve(id);
    }, Math.floor(Math.random() * 1000))
  });  
}

const promises = [[p,p,p], [p,p], [p], [p], [p,p,p,p]]

async function promiseBatchHandler(){
  for(let i = 0; i < promises.length; i++){
     const res = await Promise.all(promises[i].map((a,j)=>a(`${i}|${j}`)))
     console.log(res);
  }
}

promiseBatchHandler();
0 голосов
/ 24 января 2019

Когда вы создаете обещание, оно вызывает функцию, которую вы ему передаете. Эта функция определяет, когда обещание разрешается.

Может разрешиться до сохранения в переменной promises. Это может разрешиться гораздо позже.

Важно то, что часы начинают тикать при создании обещания.

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

Тем временем никакие другие обещания не будут выполнены.


Вместо того, чтобы хранить обещания в вашем массиве, сохраняйте данные, над которыми вы хотите работать (то есть входные данные для обещаний).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...