就像我以为我理解了承诺...我在下面的挣扎中评论了我的代码,但是从本质上讲,我只是不明白为什么当下面的代码运行时我得到以下结果
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()
})
}
答案 0 :(得分:1)
我假设readXLSX
返回了Promise
,因为您在其上使用了.then()
。 then
返回Promise
,因此,如果您希望Promise.each
正常工作,则应执行return readXLSX(...).then(...);
这是一个简化了代码的示例:
//Promise.each emulation
Promise.each = function(arr, fn) {
if(!Array.isArray(arr)) return Promise.reject(new Error("Non array passed to each"));
if(arr.length === 0) return Promise.resolve();
return arr.reduce(function(prev, cur) {
return prev.then(() => fn(cur))
}, Promise.resolve());
};
//readXLSX emulation
var readXLSX = function(val){
return new Promise(function(resolve, reject){
setTimeout(function() {
resolve(val);
}, 1);
});
};
var test = async function(file) {
var sheets = { foo: 'bar', foo2: 'bar2' }
await Promise.each(Object.values(sheets), (sheet)=>{
return readXLSX(sheet).then((data)=>{
//Process sheet data here
return processSheet(data)
});
})
console.log("Finished Processing sheets")
console.log("Processing Errors")
};
var processSheet = async function(data){
return new Promise((resolve, reject)=>{
console.log("sheet has completed processing", data)
resolve()
})
};
test();
答案 1 :(得分:1)
您的问题是您的Promise.each
回调没有return
这个承诺,因此循环无法等待它。
Promise.each(Object.values(sheets), (sheet)=>{
return readXLSX(file, { sheet }).then(processSheet)
//^^^^^^
})
或使用async
/ await
:
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
}