cRAN
cRAN

Reputation: 305

Print numbers in order, delay with which the element appears is dependent on the sequence number of the element

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

Answers (1)

Bravo
Bravo

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

Related Questions