My code is similar to the below example
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
let Promises = [];
for (let i = 0, p = Promise.resolve(); i < 10; i ) {
p = p.then(() => delay(Math.random() * 10))
.then(() => console.log(i));
}
console.log("Done");
// "Done" is getting printed before the loop executes, want it after the loop executes completely
Here is the sudo code I'm trying to build
sql query promise {
const mainArray = []
// some processing
for loop {
Step1
const temp = {}
// building a temp object
Step2
another sql query promise {
// further build temp object
// after the temp object is fully built
mainArray.add(temp);
}
}
Step3
// once the loop finishes
return mainArray
}
Execution order is - step1, step3 then step2 However, how do I make it work like step1, step2, then step3
CodePudding user response:
I would wrap all of this in an async
function to be able to use the await
keyword, and then for each instance of the loop, wrap it in a promise that resolves after your delay
const delay = ms => new Promise(resolve =>
setTimeout(resolve, ms)
);
const getRandomInt=(min,max)=>{
let range = max - min;
return parseInt(Math.random()*range) min
}
const sequentialLoop = async ()=>{
let thingsToDo = [1,2,3,4,5];
for (let i =0; i < thingsToDo.length; i ){
await new Promise (async resolve=>{
console.log('item',i,'started');
// to get a noticeable delay
let minDelay = 700 i*200
await delay(getRandomInt(minDelay,minDelay*2))
console.log('item',i,'finished')
resolve()
})
}
}
//using async
async function main(){
await sequentialLoop();
console.log('Done')
}
main()
/*
// using then
sequentialLoop().then(()=>
console.log('Done')
)
*/
CodePudding user response:
If I understand correctly your question... You whish to wait for an amount of promises (DB requests) to fill a results array... An then, use that array.
So in you example, the delay
function is just to simulate a DB request. I improved it a little by also simulating a response and making sure it would be added to a results array.
The keys to acheive it are async/await
and Promise.all()
.
See comments throughout the code.
// A function to simulate a DB request
// Notice we<re passing it the for loop index and the result array
const delay = (ms, i, results) =>
new Promise((resolve) =>
setTimeout(() => {
console.log(i " is about to resolve...");
// Simulating a response and pushing it to the result array
let fakeResult = { RequestNumber: i, response: Math.random() * 100 };
results.push(fakeResult);
resolve();
}, ms)
);
async function main() {
let promisesList = [];
let results = [];
console.log("Start!");
// Initiate every requests
for (let i = 0; i < 10; i ) {
// Push some promises here... To simulate some DB requests
promisesList.push(delay(Math.random() * 10, i, results));
}
// Await for all promises to resolve
await Promise.all(promisesList);
// Enjoy the results
console.log(results);
// You even can have them in the right order
let resultsOrdered = [...results].sort(
(a, b) => a.RequestNumber - b.RequestNumber
);
console.log(resultsOrdered);
console.log("Done");
}
main();
The console is more enjoyable in CodePen