Reputation: 5426
Just as I thought I understood promises... I have commented my code below where I am struggling, but in essence, I just can't understand why when the code below is run I get the following result
console.log("Finished Processing sheets")
console.log("Processing Errors")
console.log("sheet has completed processing")
When I would have expected
console.log("sheet has completed processing")
console.log("Finished Processing sheets")
console.log("Processing Errors")
Here is the code.
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()
})
}
Upvotes: 1
Views: 359
Reputation: 665536
Your problem is that your Promise.each
callback doesn't return
the promise, so the loop cannot wait for it.
Promise.each(Object.values(sheets), (sheet)=>{
return readXLSX(file, { sheet }).then(processSheet)
//^^^^^^
})
Or with 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
}
Upvotes: 1
Reputation: 6151
I assumed readXLSX
returns a Promise
because you use .then()
on it. then
returns a Promise
so if you want Promise.each
to work as expected, you should do return readXLSX(...).then(...);
Here is an example with your code simplified:
//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();
Upvotes: 1