Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
216 views
in Technique[技术] by (71.8m points)

JavaScript ES6 promise for loop


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As you already hinted in your question, your code creates all promises synchronously. Instead they should only be created at the time the preceding one resolves.

Secondly, each promise that is created with new Promise needs to be resolved with a call to resolve (or reject). This should be done when the timer expires. That will trigger any then callback you would have on that promise. And such a then callback (or await) is a necessity in order to implement the chain.

With those ingredients, there are several ways to perform this asynchronous chaining:

  1. With a for loop that starts with an immediately resolving promise

  2. With Array#reduce that starts with an immediately resolving promise

  3. With a function that passes itself as resolution callback

  4. With ECMAScript2017's async / await syntax

  5. With ECMAScript2020's for await...of syntax

But let me first introduce a very useful, generic function.

Promisfying setTimeout

Using setTimeout is fine, but we actually need a promise that resolves when the timer expires. So let's create such a function: this is called promisifying a function, in this case we will promisify setTimeout. It will improve the readability of the code, and can be used for all of the above options:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

See a snippet and comments for each of the options below.

1. With for

You can use a for loop, but you must make sure it doesn't create all promises synchronously. Instead you create an initial immediately resolving promise, and then chain new promises as the previous ones resolve:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

for (let i = 0, p = Promise.resolve(); i < 10; i++) {
    p = p.then(() => delay(Math.random() * 1000))
         .then(() => console.log(i));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...