This article will summarize the common application scenarios of Promise in our project development based on our own use of ES6 Promise. Of course, Promise may not be the only option, but as a qualified front-end developer, we need to understand it.
Promsie.all
Syntax: Promise.all (iterable)
Parameter: an iterative object, such as Array.
Return value:
-
If the iterable passed is empty, it is a resolved Promise.
Promise.all([]).then(res=>{ console.log(res)//[] }) Copy code
-
Promise resolved asynchronously (if the iteratable passed does not contain promise). Note that in this case, Google Chrome 58 returns the resolved commitment.
Promise.all([1,2,3]).then(res=>{ console.log(res)//[1,2,3] }) Copy code
-
When all promises in a given iteratable object are resolved, or any promises are rejected, the returned promises will be asynchronously parsed / rejected (when the stack is empty)
- When all promise s in a given iteratable object are resolved
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ resolve(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res)//[1,2,3] }) Copy code
- When any promise in a given iteratable object is rejected
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ reject(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//2 }) Copy code
Description:
This method is very useful for summarizing the results of multiple promise. In ES6, multiple Promise.all asynchronous requests can be operated in parallel:
1. When all results are returned successfully, return success in the order of request;
2. If there is one failure method, the failure method will be entered;
Scenario 1: multiple request results are combined
Specific description: a page has multiple requests. We need all the requests to return data before processing and rendering together
Thinking: if there are concurrent requests, the loading status of each request should be set separately. If there are multiple requests, multiple loading may overlap. The content displayed on the page varies according to the speed of the data returned from the request, which is reflected in the rendering process. To improve the user experience, we can use After all the requests return data, they are rendered together. At this time, we turn off the separate loading setting of the request and summarize the request results through Promise.all. From the beginning to the end, we can only set one loading.
//1. Get the data list function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('Wheel data') },300) }) } //2. Get the shop list function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('Store data') },500) }) } //3. Get the classification list function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('Categorical data') },700) }) } function initLoad(){ // loading.show() / / loading Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{ console.log(res) // loading.hide() / / close loading }).catch(err=>{ console.log(err) // loading.hide() / / close loading }) } //Data initialization initLoad() Copy code
Scenario 2: merge request results and handle errors
Description: we need to handle the data rendering and error handling logic of a single request. If there are multiple requests, we need to write them in multiple places
Thinking: can we merge multiple requests together? Even if some requests fail, they will be returned to us. We only need to process the data and wrong logic in one place.
//1. Get the data list of the carousel function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ // resolve('carousel data ') reject('Failed to get the data of the carousel') },300) }) } //2. Get the shop list function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('Store list data') },500) }) } //3. Get the classification list function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('Classification list data') },700) }) } function initLoad(){ // loading.show() Promise.all([ getBannerList().catch(err=>err), getStoreList().catch(err=>err), getCategoryList().catch(err=>err) ]).then(res=>{ console.log(res) // ["failed to get the data of carousel chart", "store data", "classification data"] if(BannerList == 'Carousel data'){ //Rendering }else{ //The logic of failed to get the data of the carousel chart } if(StoreList == 'Store list data'){ //Rendering }else{ //Logic of failed to get store list data } if(StoreList == 'Classification list data'){ //Rendering }else{ //Logic of failed to get classification list data } // loading.hide() }) } initLoad() Copy code
Sometimes the page hangs up, maybe because of the interface exception, maybe it's just a trivial interface. So why does an interface hang up causing the whole page to have no data? Project.all tells us that if there is a reject in the project parameter and the instance callback fails, the then method callback will not be executed. The above use case can solve this problem
Application scenario 3: verify whether multiple request results meet the conditions
Description: in a wechat applet project, the input content security verification of a form is done by calling the method written by the cloud function. The form has seven fields that need to be verified, all of which are called content security verification interfaces. If all of them pass the verification, they can be submitted normally
function verify1(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },200) }) } function verify2(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },700) }) } function verify3(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },300) }) } Promise.all([verify1('Verify the contents of field 1'),verify2('Verify the contents of field 2'),verify3('Verify the contents of field 3')]).then(result=>{ console.log(result)//[true, true, true] let verifyResult = result.every(item=>item) //Verification results console.log(verifyResult?'Through validation':'Failed validation')// Through validation }).catch(err=>{ console.log(err) }) Copy code
Promsie.race
Syntax: Promise.race (iterable)
Parameter: an object that iterable can iterate over, such as Array. Iterative.
Return value: the Promise.race(iterable) method returns a promise. Once a promise in the iterator is resolved or rejected, the returned promise will be resolved or rejected
The t race function returns a promise that will be completed in the same way as the first promise passed. It can be resolutions or rejections, depending on which of the two is the first way to complete.
If the passed iteration is empty, the returned promise will wait forever.
If the iteration contains one or more uncommitted values and / or resolved / rejected commitments, Promise.race resolves to the first value found in the iteration.
Application scenario 1: picture request timeout
//Request a picture resource function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; correct img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1"; }); return p; } //Delay function for timing requests function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('Picture request timeout'); }, 5000); }); return p; } Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); }); Copy code
Application scenario 2: request timeout prompt
Caption: sometimes, we brush the news one second ago, and when we enter the elevator the next, you will be prompted "bad network" on the mobile page
//request function request(){ return new Promise(function(resolve, reject){ setTimeout(()=>{ resolve('Request successful') },4000) }) } //Request timeout alert function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('Poor network'); }, 3000); }); return p; } Promise.race([ request(), timeout() ]) .then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//Poor network }) Copy code
Promise..prototype.then
Scenario 1: the next request depends on the result of the previous request
Description: similar to WeChat applet login, first you need to execute the WeChat small program login wx.login, return to code, then call the login interface written at the back end, import code, and then return to token, and then each request must carry token, that is, the next request depends on the data returned by the previous request.
function A(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('B Dependent data') },300) }) } function B(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams + 'C Dependent data') },500) }) } function C(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams) },1000) }) } //What we expect is to try. Since there is no reject in the requests simulated by A B C, try catch is used to catch errors try{ A().then( res=>B(res) ).then( res=>C(res) ).then( res=>{ console.log(res)//Data dependent on B data dependent on C }) } catch(e){ } Copy code
Application scenario 2: middleware function usage
Description: the amount of data returned by the interface is relatively large, and it seems bloated to process in one then. Multiple render data are given to each then to perform their respective duties
//Simulate the data returned by the backend let result = { bannerList:[ {img:'Broadcast map address'} //... ], storeList:[ {name:'Shop list'} //... ], categoryList:[ {name:'Classification list'} //... ], //... } function getInfo(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(result) },500) }) } getInfo().then(res=>{ let { bannerList } = res //Rendering a carousel console.log(bannerList) return res }).then(res=>{ let { storeList } = res //Render store list console.log(storeList) return res }).then(res=>{ let { categoryList } = res console.log(categoryList) //Render classification list return res }) Copy code
reference material:
Chinese Promise - JavaScript | MDN
Conclusion:
If you have a better idea, please leave a message
If there is any inaccuracy or mistake in the text, please point out
Previous articles:
- When all promise s in a given iteratable object are resolved