Promise.all()在Node中的行为非常奇怪

时间:2019-01-24 11:39:33

标签: javascript node.js promise

在NodeJS中使用Promises时遇到一个非常奇怪的错误。我有一个包含诺言数组的数组。

示例:

  

let promises = [[P1,P2,P3],[P4,P5],[P6],[P7,P8],[P9,P10,P11,   P12,P13]]

现在,如果我将promise数组提供给以下代码,则我希望依次解析每组promise。

(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步:promise数组中的所有promise都将执行

第3步:解决所有的诺言后,循环将继续进行下一个迭代。

预期输出:第一组承诺解析->迭代->第二组承诺->迭代等等

我丢失了某些东西还是节点执行Promises的方式不同?

2 个答案:

答案 0 :(得分:3)

创建承诺时,它将调用传递给它的函数。该函数确定诺言何时解决。

在将其存储在promises变量中之前,它可以解析。它可能会在以后解决。

重要的是,创建承诺后,时钟开始计时。

使用Promise.all可让您在传递给它的所有承诺都得到解决后运行一个函数。

在此期间,它不会阻止其他任何承诺的达成。


不是将promise存储在数组中,而是存储要处理的数据(即promise的输入)。

在循环内启动promise,并使用Promise.all等待它们全部解决,然后再开始下一组。

答案 1 :(得分:0)

将用于创建承诺的函数存储在数组中(而不是 actual 承诺本身)。

然后遍历每个对象,调用将创建您的Promise的函数(并运行它)并等待该批处理完成。批处理完成后,请转到下一个。

//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();