Problems/Requirements:
- Anyway, the interviewer has asked us to do the basics
Promise
, includingpromise
The callbackresolve
andreject
And those returned after processing the state.then
Method, so next, we will continue to implementPromise
The method of processing multiple asynchronous requests/processing after completion, output againall
Solution/Handling procedure
Analysis process:
- The parameter of the all method is an array. In this array, it is supposed to store the data of the promise type, but (as we all know, not all cases in this world are ideal, so, need to be processed, but, First of all, let’s just say that if is the norm, the data in the array is of type promise.
The preliminary implementation
- First basic processing, according to the passed parameters, traversal, return data. And see what the problem is
// The basic implementation and method of promise are not posted here, you can check the series 1 article, here are the main points
all(promises) {
// All can also be chained, so we need to return a promise like then
return new Promise((resolve, reject) = > {
let res = [] // An array to store all the results returned after processing
const length = promises.length // The array length of the argument passed in
promise.forEach((promise, index) = >{
// Iterate over each promise object in the array, calling its then method to retrieve resolve or Reject data
promise.then(result= > {
// handle a push
res.push(result)
// Resolve returns when the res result array is the same length as the passed argument
if(res.length === promiseLength) resolve(res)
}).catch(e= > reject(e))
})
})
})
}
Copy the code
- ForEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach forEach So, here’s a type judgment.
// The basic implementation and method of promise are not posted here, you can check the series 1 article, here are the main points
all(promises) {
// All can also be chained, so we need to return a promise like then
return new Promise((resolve, reject) = >{+if(!Array.isArray(promises)){
+ // pit 1: Reject the data type of the passed parameter. If it is not an array type, reject throws a message
+ return reject('The argument passed must be in array format! ') +}let res = [] // An array to store all the results returned after processing
const length = promises.length // The array length of the argument passed in
promise.forEach((promise, index) = >{
// Iterate over each promise object in the array, calling its then method to retrieve resolve or Reject data
promise.then(result= > {
// handle a push
res.push(result)
// Resolve returns when the res result array is the same length as the passed argument
if(res.length === promiseLength) resolve(res)
}).catch(e= > reject(e))
})
})
})
}
Copy the code
- At this point, the parameter type passed in is fine, but! The forEach loop iterates through each object, calling the. Then method directly, and if the data being iterated is not a promise object from the suture specification, then an error will be reported. If it is not a Promise object, return the current iterated object. No then operation is performed, but! There’s actually a good trick here. Take a look below.
promise.forEach((promise, index) = >{
// If a promise is a promise, it can be a number or something else.
// The Promise static resolve method is now a Promise type, regardless of whether it was originally a Promise
let res = []
const promiseLength= promises.length
Promise.resolve(promise).then(result= > {
// Pit 3: There should be a counter here, because promise.all is returned sequentially, not sequentially with I
// handle a push
res.push(result)
// Resolve returns when the res result array is the same length as the passed argument
if(res.length === promiseLength) resolve(res)
}).catch(e= > reject(e))
Copy the code
- That may someone will say, so should have no what problem! The parameter passed in determines the type, and the current object type traversed is handled. Yes, the data type passed in is now handled. Do you notice anything about the output? The order of the results returned by the all method corresponds to the order of the parameters passed in. The order of the results returned by the all method corresponds to the order of the parameters passed in. Here’s a look:
promise.forEach((promise, index) = >{
// If a promise is a promise, it can be a number or something else.
// The Promise static resolve method is now a Promise type, regardless of whether it was originally a Promise
let res= []
const promiseLength= promises.length
Promise.resolve(promise).then(result= > {
// Pit 3: There should be a counter here, because promise.all is returned sequentially, not sequentially with I
+ res[index] = result // Use the subscript of the current traversal to store the output in the same order
// handle a push
- res.push(result) // Not push directly, because asynchrony does not guarantee that the results will be returned in order
// Resolve returns when the res result array is the same length as the passed argument
if(res.length === promiseLength) resolve(res)
}).catch(e= > reject(e))
Copy the code
- Here, solved the output order problem, there should be no problem! The interviewer asks, “Have you considered what would happen to your program if the last index was printed first?” “, here look there take a look, heart OS: “no problem ah”, “really no problem? If the last one is the first one, then the length of the array is the same as the length of the argument passed in.
promise.forEach((promise, index) = >{
// If a promise is a promise, it can be a number or something else.
// The Promise static resolve method is now a Promise type, regardless of whether it was originally a Promise
let res= []
+ let count = 0 // It is used to record how much data is processed
const promiseLength= promises.length
Promise.resolve(promise).then(result= > {
// Pit 3: There should be a counter here, because promise.all is returned sequentially, not sequentially with I
res[index] = result // Use the subscript of the current traversal to store the output in the same order
+ count++ // Process one counter plus one
- // Resolve returns when the res result array is the same length as the passed argument
- if(res.length === promiseLength) resolve(res)
+ if(count === promiseLength) resolve(res) // This parameter is returned only when the number of processes is in the same format as the parameter
}).catch(e= > reject(e))
Copy the code
-
At this point, the promise.all methods are complete. In fact, usually feel very convenient to use, but also need to know why, learning to learn the excellent code crystallization of predecessors, even for their own a little bit of 🤏 promotion is also good.
-
Finally, to the all method of all implementation and a few points to note ⚠️:
// The basic implementation and method of promise are not posted here, you can check the series 1 article, here are the main points all(promises) { // All can also be chained, so we need to return a promise like then return new Promise((resolve, reject) = > { if(!Array.isArray(promises)){ // pit 1: Reject the data type of the passed parameter. If it is not an array type, reject throws a message return reject('The argument passed must be in array format! ')}let res = [] // An array to store all the results returned after processing let count = 0 // The number of requests/data that have been processed const length = promises.length // The array length of the argument passed in promise.forEach((promise, index) = >{ // Pit 2: This is supposed to determine if a promise is a promise, because it could be a number or something else. // The Promise static resolve method is now a Promise type, regardless of whether it was originally a Promise Promise.resolve(promise).then(result= > { // Pit 3: There should be a counter here, because promise.all is returned sequentially, not sequentially with I count ++ res[index] = result // pit 4: there is an error in using length, because if there is a seventh array in js, the length is still 7(undefined). if(count === promiseLength) resolve(res) }).catch(e= > reject(e)) }) }) }) } Copy the code