Javascript 如何在嵌套函数调用中使用承诺

Javascript 如何在嵌套函数调用中使用承诺,javascript,node.js,promise,Javascript,Node.js,Promise,就像我认为我理解承诺一样。。。我已经在下面的代码中注释了我正在努力的地方,但本质上,我不明白为什么在运行下面的代码时会得到以下结果 console.log("Finished Processing sheets") console.log("Processing Errors") console.log("sheet has completed processing") 当我预料到的时候 console.log("sheet has completed processing") console

就像我认为我理解承诺一样。。。我已经在下面的代码中注释了我正在努力的地方,但本质上,我不明白为什么在运行下面的代码时会得到以下结果

console.log("Finished Processing sheets")
console.log("Processing Errors")
console.log("sheet has completed processing")
当我预料到的时候

console.log("sheet has completed processing")
console.log("Finished Processing sheets")
console.log("Processing Errors")
这是代码

module.exports = async function(file) {
var sheets = await readXLSX(file, { getSheets: true })

  await Promise.each(Object.values(sheets), (sheet)=>{
    readXLSX(file, { sheet }).then((data)=>{
      //Process sheet data here
      return processSheet(data)
    })
  })
  console.log("Finished Processing sheets")
  console.log("Processing Errors")

}
var processSheet = async function(data){
//Do some processing and write excel data to database
await db.table('some_table')
.insert(.....)

return new Promise((resolve, reject)=>{
console.log("sheet has completed processing")
resolve()
})
}

我假设
readXLSX
返回一个
Promise
,因为您在它上面使用了
.then()
然后
返回一个
承诺
因此,如果您希望
承诺。每个
要按预期工作,您应该执行
返回readXLSX(…)。然后(…)

下面是一个代码简化的示例:

//Promise.each仿真
Promise.each=函数(arr,fn){
if(!Array.isArray(arr))返回Promise.reject(新错误(“非数组传递给每个数组”);
if(arr.length==0)返回Promise.resolve();
返回arr.reduce(函数(prev,cur){
返回上一个然后(()=>fn(当前))
},Promise.resolve());
};
//readXLSX仿真
var readXLSX=函数(val){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解决(val);
}, 1);
});
};
var test=异步函数(文件){
变量表={foo:'bar',foo2:'bar2'}
等待承诺。每个(对象。值(表),(表)=>{
返回readXLSX(表)。然后((数据)=>{
//此处为流程表数据
返回流程表(数据)
});
})
console.log(“已完成的处理表”)
日志(“处理错误”)
};
var processSheet=异步函数(数据){
返回新承诺((解决、拒绝)=>{
console.log(“工作表已完成处理”,数据)
解决()
})
};

test()
您的问题是您的
承诺。每个
回调都不会
返回
承诺,因此循环无法等待它

Promise.each(Object.values(sheets), (sheet)=>{
  return readXLSX(file, { sheet }).then(processSheet)
//^^^^^^
})
或使用
异步
/
等待

module.exports = async function(file) {
  const sheets = await readXLSX(file, { getSheets: true })

  await Promise.each(Object.values(sheets), async (sheet) => {
//                                          ^^^^^
    const data = await readXLSX(file, { sheet })
    return processSheet(data)
  })
  console.log("Finished Processing sheets")
  console.log("Processing Errors")
}

async function processSheet(data) {
  await db.table('some_table').insert(…)
  console.log("sheet has completed processing");
  return undefined; // no need to construct a promise here
}

等待承诺。每个
都希望第二个参数是返回承诺的函数。你没有那样做。如果您
返回readXLSX(…)
我认为您的问题将(部分?)得到解决。