With the development of modern browsers, we believe that ES6 Promise has been a lot of use, including Promise. All is estimated to use a lot. Promise.all is the execution of multiple tasks in parallel, and then is triggered when all tasks succeed, or catch is triggered when any task fails.
While promise.all is very useful, it is not suitable for all scenarios, most commonly some scenarios need to be serial, a list of tasks needs to be executed in a sequence, and any failure does not trigger any of the following tasks. So how do you write that?
The easiest thing to do is just write it one by one
var a = ()=>{return new Promise((resolve, reject) => { setTimeout(resolve, 1000); }); } var b = ()=>{return new Promise((resolve, reject) => { setTimeout(resolve, 1000); }); } var c = ()=>{return new Promise((resolve, reject) => { setTimeout(resolve, 1000); }); } a().then(()=>{ return b() }).then(()=>{ return c() }).then(()=>{ console.log('after 3 sec') })Copy the code
Write it this way… It’s really frustrating, but more importantly, sometimes you need to batch a task, all calling the same function to handle variable length of data, which is definitely not possible to write, such as requesting a series of urls. The first thing that came to mind was a more convoluted approach. Make a Promise chain, pass the next task as a parameter to the previous one’s THEN, and so on. The same function loops over and over again and passes the previous value to the parameter, which is consistent with the array.reduce idea, so it can be written like this:
var urlArr = ['http://www.qq.com','http://www.qq.com','http://www.qq.com'];
function makaPromiseList(dataArr,handler) {
return dataArr.reduce((promise, obj) => {
return promise.then((ret) => {
return handler(obj);
})
}, Promise.resolve())
}
var result = [];
function makeRequest(url){
return new Promise((resolve,reject)=>{
$.get(url).success((ret)=>{
result.push(ret)
resolve(result)
}).fail(()=>{
reject()
})
})
}
makaPromiseList(urlArr,makeRequest).then((result)=>{
console.log(result)
});Copy the code
The teacher does not give force, it is very difficult to understand, and it needs to define result to save data outside the closure. It also feels a little strange and crafty to use reduce, which is not very beautiful. Can you write it better? You can! Promise is strong when it comes to asynchronous schemes, but it’s not the strongest yet, and there’s an advanced version of Promise — async/await! The ultimate async/await solution for JS async is not covered, so let’s look at async/await solutions
var urlArr = ['http://www.qq.com','http://www.qq.com','http://www.qq.com']; function makeRequest(url){ return new Promise((resolve,reject)=>{ $.get(url).success((ret)=>{ resolve(ret) }).fail(()=>{ reject() }) }) } async function makaPromiseList(dataArr,handler){ var result = []; for(let item of dataArr){ var ret = await handler(item); result.push(ret); } return result; } makaPromiseList(urlArr,makeRequest).then((ret)=>{ console.log(ret) });Copy the code
A for loop solves the serial asynchrony problem, no callbacks and no nesting looks instantly more comfortable