Reputation: 305
I want to print a sequence of numbers; it should always start with 1 and be shown after a delay of 1s (1000ms). The next number in the list, 2 should be printed after a delay of 2 seconds, after the previous one, i.e 1 has been printed and so on until the given limit is reached. It has be done sequentially.
1 should print at time 1 second
2 should print at time 3 seconds
3 should print at time 6 seconds and so on..
I had two approaches in mind, either using Promises or using Generator function/async-await
My question is regarding the first approach, i.e, using Promise.
a. When using setTimeout, I am not getting the correct order
b. Whereas using a block/delay function gives me the correct result.
a. When using setTimeout, I am not getting the correct order
Reasons which contradict this behavior: Every task passed to the Timer functionality of the browser/Node.js, waits for the timeout to be completed, once done, pushes the task to the call stack.
Promise.then guarantees that the previous thenable is resolved before taking up the next function/callback form the onFullfillment array.
Can someone please advise me with a correct intuition or help me with correct understanding.
(function printAsyncInOrder(limit) {
let [, ...list] = [...Array(limit + 1).keys()];
list.reduce(chainedSequence, Promise.resolve());
function chainedSequence(chain, currentOrder, index) {
return chain.then(() => {
let i = index;
let current = currentOrder;
// setTimeout(() => console.log(`Hi ${index} ${new Date()}`), i * 1000)
blocker(current * 1000);
});
}
function blocker(time) {
let timeNow = new Date();
while (new Date() - timeNow < time) {}
console.log(`hi ${time} ${new Date()}`);
}
})(10);
Using setTimeout:
Hi 2 Sun Nov 10 2019 11:37:44
Hi 3 Sun Nov 10 2019 11:37:45
Hi 4 Sun Nov 10 2019 11:37:46
Hi 5 Sun Nov 10 2019 11:37:47
Hi 6 Sun Nov 10 2019 11:37:48
Hi 7 Sun Nov 10 2019 11:37:49
Hi 8 Sun Nov 10 2019 11:37:50
Hi 9 Sun Nov 10 2019 11:37:51
Hi 10 Sun Nov 10 2019 11:37:52
using blocker/delay function
hi 2000 Sun Nov 10 2019 11:38:29
hi 3000 Sun Nov 10 2019 11:38:32
hi 4000 Sun Nov 10 2019 11:38:36
hi 5000 Sun Nov 10 2019 11:38:41
hi 6000 Sun Nov 10 2019 11:38:47
hi 7000 Sun Nov 10 2019 11:38:54
hi 8000 Sun Nov 10 2019 11:39:02
hi 9000 Sun Nov 10 2019 11:39:11
hi 10000 Sun Nov 10 2019 11:39:21
Upvotes: 0
Views: 549
Reputation: 6263
you'll need to return a Promise in chain.then(() => {
that resolves after the timeout expires
like this
(function printAsyncInOrder(limit) {
let [, ...list] = [...Array(limit + 1).keys()];
list.reduce(chainedSequence, Promise.resolve());
function chainedSequence(chain, currentOrder, index) {
return chain.then(() => {
let current = currentOrder;
return new Promise(resolve => setTimeout(() => {
console.log(`Hi ${index} ${new Date()}`);
resolve();
}, 1000 * index));
});
}
})(10);
Upvotes: 0