Be sure to like it and watch again! ๐Ÿคจ

Words do not say, first look at the following test

Use promise.all to make 5 requests. If one of them fails, how do I get the other 4 to return successfully? ๐Ÿฅณ

I believe that the vast majority of students, see this topic is a face meng forced

Let’s look at the basic usage of promise. all

Promise. All usage

let p1 = Promise.resolve(1) let p2 = Promise.resolve(2) let p3 = new Promise((resolve) => { setTimeout(() => { resolve(3) }, 2000); }) Promise.all([p1, p2, p3]).then((res) => { console.log('res', res); / / print out after 2 s [1, 2, 3]}). The catch ((err) = > {the console. The log (' err, err); })Copy the code

The above code will print [1, 2, 3] after 2s;

As you can see, the promise.all () method passes in an array of iterable promises. When all promises are successfully executed, promise.all completes and returns a Promise. The result of the Promise resolve is an array of the return results of the passed promise.

If all three promises succeed, let’s see what happens if one of them fails.

let p1 = Promise.resolve(1) let p2 = Promise.reject(2) let p3 = new Promise((resolve) => { setTimeout(() => { resolve(3) }, 2000); }) Promise.all([p1, p2, p3]).then((res) => { console.log('res', res); }).catch((err) => { console.log('err', err); // Print err 2 immediately})Copy the code

When one of the promises fails, an error is immediately thrown, indicating that the whole promise.all operation fails.

Look at this, some students will say:

Yes, the above usage of Promise. All I believe that the vast majority of front-end students have mastered, but to solve the problem, we still step by step, first understand its usage, and then understand the principle, so that we will have a deep grasp.

The realization of the Promise. All

Now that we know the basics, we can roll out a method on our own to implement promise.all

The basic implementation ideas are summarized as follows:

  1. Accepts a parameter of array type
  2. When all the promises in the array have been successfully executed, a new promise is returned as their result set
  3. If one of them fails, the state becomes Rejected

Following these ideas, we can roughly write the following methods:

function myAll(arr) { let length = arr.length; Let currentCount = 0; // Record the current execution of the subscript let results = []; Return new Promise((resolve, reject) => {for (let I = 0; i < arr.length; i++) { Promise.resolve(arr[i]).then((res) => { results[i] = res; // store it in results, subscript currentCount++; If (currentCount === length) {resolve(results)}}). Catch ((err) => {reject(err) If (length === 0) {resolve(results)})}Copy the code

After testing, this method is consistent with the results of promise. all. Students can try it on their own without too much demonstration here

(PS: About the implementation of promise. all, there are several versions on the Internet, in my opinion, as long as the above implementation ideas are written, are all changes.)

See here, some students can not sit still, this with the beginning mentioned that interview question, and what relationship?

Everyone calm down, the answer has slowly emerged ๐Ÿ‘‡

Promise. All the rewrite

By looking at the implementation of promise.all above, we can see that if one of the promises fails, we execute reject, and the outside world immediately catches the error from the catch and returns the error

What if I fail and return a result?

Now let’s change the above code, the idea of change is very simple:

When a promise fails, reject is not executed and false is returned as result

function myAll(arr) { let length = arr.length; Let currentCount = 0; // Record the current execution of the subscript let results = []; Return new Promise((resolve, reject) => {for (let I = 0; i < arr.length; i++) { Promise.resolve(arr[i]).then((res) => { results[i] = res; }). Catch ((err) => {results[I] = false; }).finally(() => {currentCount++; If (currentCount === length) {resolve(results)}})} Results if(length === 0) {resolve(results)}}Copy the code

After the above rewriting, let’s test the code

let p1 = Promise.resolve(1) let p2 = Promise.resolve(2) let p3 = new Promise((resolve, reject) => { setTimeout(() => { reject(3) }, 2000); }) myAll([p1, p2, p3]). Then (res => {console.log(res) // 2s after printing [1, 2, false]}). Catch (err => {console.log('err', err) })Copy the code

See here, you should have a kind of suddenly enlightened, suddenly enlightened feeling

In fact, each promise will resolve and reject if it succeeds and reject if it fails, so if we return a variable instead of reject when it fails, we’ll get the answer!

answer

We know that promise. all accepts an array, and we reject every reject in the array when a Promise fails, which leads us to the array map method

let p1 = Promise.resolve(1) let p2 = Promise.resolve(2) let p3 = new Promise((resolve, reject) => { setTimeout(() => { reject(3) }, 2000); }) let all = Promise.all([p1, p2, p3].map((p) => p.then(res => res).catch(err => false))) all.then((res) => { console.log(res, Res. Filter (Boolean)) / / 2 s after printing [1, 2, false], [1, 2]}). The catch ((err) = > {the console. The log (' err, err)})Copy the code

As you can see, the most critical part of this code is the catch processing. Instead of executing reject, false is returned, so that even if the execution fails, the catch in all is not caught, and all results are returned.

In fact, as early as in the ES6 proposal, there is a related implementation method ๐Ÿ‘‡

About Promise. AllSettled

Because a single Promise enters the Rejected state, the result of promise.all () will immediately enter the Rejected state, so that when it enters the Rejected state through promise.all (), The source Promise may still be in a pending state, so that all Promise completion times are not available.

Thus, a new promise.allSettled () API is proposed, where the definition of Settled state is not pending, which is a depressing or rejected state. It waits for all source promises to enter the fulfilled or Rejected state.

Code demo:

let p1 = Promise.resolve(1) let p2 = Promise.resolve(2) let p3 = new Promise((resolve, reject) => { setTimeout(() => { reject(3) }, 2000); }) Promise. AllSettled ([P1, P2, p3]). Then (res => {console.log(res) //2s later print [{status: "depressing ", value: 1}, {status: "fulfilled", value: 2}, {status: "rejected", reason: 3}] }).catch(err => { console.log('err', err) })Copy the code

Of course, we also need to map the returned RES, so as to achieve the results obtained in the above interview questions, this part of the students to try their own ~

conclusion

After reading this article, I believe that you have a deep understanding of the use of Promise. All, the next time encountered about the Promise. All situation and the topic should also be able to be handy, easy to play.

This article ends here, have different opinions and opinions welcome to put forward ~

Be sure to like it and watch again!