As a front-end dregs, I met an interview question of serial implementation of a Promise in the interview yesterday, but I didn’t make it at that time. Today, I reconsidered and made a small summary.
The title
Let’s take a look at the problem, which basically says, I give you an incomplete piece of code to fill in
let arr = [ new Promise(res=>{ setTimeout(()=>{ res(1) },1000) }), new Promise(res=>{ setTimeout(()=>{ res(2) },1000) }), New Promise(res=>{setTimeout(()=>{res(3)},1000)})] function iteratorPromise(arr){// add code} iteratorPromise(arr);Copy the code
Define an array of promises, execute them sequentially, and finally implement the following output
Promise. All returns an array, and even if that array is used… Extension operator, the three arrays are displayed on another line, does not meet the requirements of the problem.
So how do you implement serial display? Then returns a previous Promise. Then returns the next Promise; It looks like this:
Promise1.then((num)=>{ //... Return Promise2. Then ((num)=>{//... Return Promise3}})Copy the code
This allows the first Promise to be implemented, followed by the second Promise, and so on
Ok, with that in mind, it’s pretty easy to implement, and I use the dumbest method of all — for traversal.
function iteratorPromise(arr){ for(let i = 0; i<arr.length; i++){ arr[i].then((num)=>{ console.log(num) return arr[i+1] }) } }Copy the code
Reduce can also be used as an array reduce method, but there is a disadvantage of reduce. It can’t execute the last method’s THEN, that is, it can’t print 3, because it just returns Promise3, but the Promise doesn’t set its THEN. So I chose the above method
arr.reduce((pre,cur)=>{
return pre.then((num)=>{
num && console.log(num)
return cur
})
},Promise.resolve())
Copy the code
Here, the problem is solved!! And the flower
supplement
Here, through some blogs, I found that serial can be solved in a more ingenious way, although this method is not suitable for the interview question I encountered yesterday, but it is well worth noting:
// Each entry in the array is a function. This function returns a promise, which means we don't need to write a new function in then. let arr = [()=>{ return new Promise(res=>{ setTimeout(()=>{ console.log("run", Date.now()); res() },1000) }) },()=>{ return new Promise(res=>{ setTimeout(()=>{ console.log("run", Date.now()); res() },1000) }) },()=>{ return new Promise(res=>{ setTimeout(()=>{ console.log("run", Date.now()); res() },1000) }) }] function iteratorPromise(arr){ let res = Promise.resolve(); Arr. ForEach (fn=>{res = res.then(()=>fn()))})} iteratorPromise(arr); if (fn=>{res = res.then(()=>fn()))Copy the code
The essence is the same: let the then of the previous Promise return the next Promise, chained together
Review the knowledge
We know that there are two apis that allow us to implement multiple promises at the same time, all and Race
Promise.all
As the name implies, this is to execute all promises, but it should be noted that the successful return result is an array of the results of multiple promises. If all promises succeed, the success array will be returned. If only one Promise fails, the failure callback will be triggered. Returns error information for the first failed Promise.
Example: on the MDN Promise. All () – JavaScript | MDN (mozilla.org)
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]数组的形式
});
Copy the code
Its use is actually very simple we need to remember a few points can be:
- Returns the result of success as an array
- If the parameter contains not
promise
Value, which will be ignored but will still be placed in the return array (ifpromise
Done) - Whenever there is a failure, the failure callback is triggered, returning information about the first failure
- P1, P2, p3, incoming
promise
Incoming order execution (although P1 may be slower than P2)
Promise.race
As the name implies, multiple promises are passed in, and whichever promise is first fulfilled is returned, regardless of whether the result is a success or failure:
Example: on the MDN Promise. Race () – JavaScript | MDN (mozilla.org)
var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "one"); }); var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "two"); }); Promise.race([p1, p2]).then(function(value) { console.log(value); // "two" // both complete, but p2 is faster});Copy the code
It feels even simpler than All, but it uses very few scenarios.
OVER!!!