Recently, the interviewer asked him to write a promise. All. He thought the question was worth thinking about, so he wrote it down here.

Understand the promise. All

We need to write the promise.all method by hand. First we need to see what this method does. Look at the code below.

// First promise instance const p1 = new promise ((res, rej) => {res(1)}) rej) => { res(2) }) // promise.all() promise.all(p1, p2).then(res => { console.log(res) }).catch(err => { console.log(err) })Copy the code

First, the result of the above code is "[1, 2]".

As you can see from the code, the all method receives a promise instance as an argument. The definition of the All method is to execute the then when all the received instances are completed and all the returned res are executed. If one of the received instances executes rej, then the catch is executed.

Then receives an array, and the results of the array are ordered. Order is the order in which the results of the passed instance are executed, so the result is “[1, 2]”.

Now that we know what all does and what it returns, let’s write.

Implement myAll

First, we know that the all method is followed by a call to the then function, so we know that myAll should return a Promise instance.

function myAll() {
    return new Promise((resolve, reject) => {})
}
Copy the code

Now you can fix the parameters. You know that the parameters you’re receiving are Promise instances, but you don’t know how many parameters you need to accept, so you can do this with auguments, or with the ES6 extension operators (…). To implement.

function myAll(... p) { return new Promise((resolve, reject) => {}) }Copy the code

With the problem of parameter acceptance resolved, you can now use loops to execute each instance.

function myAll(... p) { return new Promise((resolve, reject) => { for(let i = 0; i < p.length; I++) {p [I]. Then (res = > {/ / each instance the result returned}). The catch (err = > {reject (err)})}})}Copy the code

Next question, we already know that myAll needs to listen for the results of all promise instances. So how do we determine how many promise instances are executed? That’s right, we can count with a variable that starts at 0, each promise completes with a value of +1, and when the value of the variable matches the length of the instance, we can be sure that all instances have been executed.

What if one of the instances executes into a catch? Instead of changing the value of the variable, we simply reject the error in myAll.

function myAll(... p) { return new Promise((resolve, reject) => { let index = 0 for(let i = 0; i < p.length; I ++) {p[I]. Then (res => {index ++ if(index === p.length) { Catch (err => {reject(err)})}Copy the code

The last question is, we know that the then after all method receives an array, and it is an ordered array. How to implement this? We can construct an instance of the same length of data, and then store the results in order using the array’s subscripts, which correspond to the I of the for loop.

Note: if I is defined by var in the for loop, note the problem of variable promotion

/* function myAll(... p) { return new Promise((resolve, reject) => { let index = 0 const res = new Array(p.length) for(let i = 0; i < p.length; i++) { p[i].then(res => { res[i] = res index ++ if(index === p.length) { resolve(res) } }).catch(err => { reject(err) }) }})}Copy the code

Thank you for watching.