Author: D827
Source: Hang Seng LIGHT cloud community
None of the functions will not be used after reading the source code. So after reading this article, I hope it can help you completely master Promise.
Promise introduction
Promise object is a solution to realize asynchrony provided by ES6. It enables asynchronous methods to return values like synchronous methods.
promise is a constructor that wraps (encapsulates) an asynchronous function (ajax; timer; database read; fs file read). Of course, it can also wrap a non asynchronous function. The input parameters are two functions: resolve and reject. Resolve is called successfully and parameters are passed. Reject is called and parameters are passed in case of failure. use. then is used as the callback result. then accepts two function parameters. The first parameter accepts the correct return result, and the second function receives the wrong return result.
Promise has three statuses: pending, fullfilled/resolved, and rejected
The initial state of Promise is pending, and the state is modified to fullfilled/resolved through the resolve method; Change the status to rejected by reject
promise's advantages: it can realize chain call and solve the callback hell caused by asynchronous callback.
Disadvantages of promise:
- Unable to monitor the status of progress, execute the new immediately, and cannot cancel;
- If the callback function is not set, the error thrown by Promise will not be reflected to the outside;
- Sometimes it will cause multiple then chain calls, which may cause the semantics of the code to be unclear.
Basic use of Promise
function sleep(data){ return new Promise((resolve,reject)=>{ // The new Promise package can be an asynchronous code or a synchronous code // Code execution succeeded setTimeOut(()=>{ let result = null if(1){ resolve(result) }else{ reject(result) } },1000) }) } sleep(1000).then(v=>{ // Correct return processing },e=>{ // Error return processing }).then(v=>{ }).then(v=>{ }) ...... .catch(e=>{ // error handling })
Problems needing attention and solutions for customizing Promise
promise how to modify the status
Modify the status by calling resolve and reject
Can the status be modified by calling resolve and reject multiple times
No, it cannot be changed to another state after changing from pending to resolved or rejected
Whether promise modifies the status first or displays the execution then, and when to get the data
Both situations may occur. When the content of promise package is asynchronous, specify then and then modify the state. On the contrary, modify the state first and then execute then;
The data is obtained after the callback is executed.
promise.then returns a promise. Who decides the returned type result
The returned is promise, which is determined by the returned promise
If the return is non promise, it is resolved
How promise concatenates multiple operation tasks
Because Promise Then returns a new Promise object, so you can also call then to implement the chain call
promise exception penetration
It means that no matter how many then there are, any one of them will be caught by the catch if an error is reported
How to terminate promise chain
Any one of then is abnormal;
Change the state of promise to pending in any then.
Promise customization
//Declaration constructor function Promise(executor){ //Add attribute this.PromiseState = 'pending'; this.PromiseResult = null; //There are multiple cases of declaring property callbacks this.callbacks = []; //Save the value of this of the instance object const self = this;// self _this that //resolve function function resolve(data){ //Judge the status and call resolve and reject multiple times. The status cannot be modified if(self.PromiseState !== 'pending') return; //1. Modify the object's state (promiseState) self.PromiseState = 'fulfilled';// resolved //2. Set the object result value (promiseResult) self.PromiseResult = data; //Call successful callback function setTimeout(() => { self.callbacks.forEach(item => { item.onResolved(data); }); }); } //reject function function reject(data){ //Judgment state if(self.PromiseState !== 'pending') return; //1. Modify the object's state (promiseState) self.PromiseState = 'rejected';// //2. Set the object result value (promiseResult) self.PromiseResult = data; //Failed callback execution setTimeout(() => { self.callbacks.forEach(item => { item.onRejected(data); }); }); } try{ //Synchronously call "actuator function" executor(resolve, reject); }catch(e){ //Modify the promise object status to fail reject(e); } } //Add then method Promise.prototype.then = function(onResolved, onRejected){ const self = this; //Determine callback function parameters if(typeof onRejected !== 'function'){ onRejected = reason => { throw reason; } } if(typeof onResolved !== 'function'){ onResolved = value => value; //value => { return value}; } return new Promise((resolve, reject) => { //Encapsulation function function callback(type){ try{ //Get the execution result of the callback function let result = type(self.PromiseResult); //judge if(result instanceof Promise){ //If it is an object of Promise type result.then(v => { resolve(v); }, r=>{ reject(r); }) }else{ //The object status of the result is success resolve(result); } }catch(e){ reject(e); } } //Call the callback function PromiseState if(this.PromiseState === 'fulfilled'){ setTimeout(() => { callback(onResolved); }); } if(this.PromiseState === 'rejected'){ setTimeout(() => { callback(onRejected); }); } //Determine pending status if(this.PromiseState === 'pending'){ // Save the callback function in asynchronous mode, and execute the callback function after asynchronous execution this.callbacks.push({ onResolved: function(){ callback(onResolved); }, onRejected: function(){ callback(onRejected); } }); } }) } //Add catch method Promise.prototype.catch = function(onRejected){ return this.then(undefined, onRejected); } //Add resolve method Promise.resolve = function(value){ //Return promise object return new Promise((resolve, reject) => { if(value instanceof Promise){ value.then(v=>{ resolve(v); }, r=>{ reject(r); }) }else{ //The status is set to success resolve(value); } }); } //Add reject method Promise.reject = function(reason){ return new Promise((resolve, reject)=>{ reject(reason); }); } //Add all method Promise.all = function(promises){ //The returned result is promise object return new Promise((resolve, reject) => { //Declare variable let count = 0; let arr = []; //ergodic for(let i=0;i<promises.length;i++){ // promises[i].then(v => { //Know that the status of the object is successful //Each promise object succeeded count++; //Store the successful result of the current promise object into the array arr[i] = v; //judge if(count === promises.length){ //modify state resolve(arr); } }, r => { reject(r); }); } }); } //Add race method Promise.race = function(promises){ return new Promise((resolve, reject) => { for(let i=0;i<promises.length;i++){ promises[i].then(v => { //Modify the status of the returned object to success resolve(v); },r=>{ //Modify the status of the returned object to "failed" reject(r); }) } }); }
I hope the above content is helpful to you!
Want to learn more from technology bosses? Where to discuss the problems encountered in development? How to obtain massive financial technology resources?
Hang Seng LIGHT cloud community , the financial technology professional community platform built by Hang Seng electronics shares practical technology dry goods, resource data and financial technology industry trends, and embraces all financial developers.
Scan the QR code of the applet below and join us!