Promise/A + specification

I. Application scenarios of Promise

  • For example, we often need to request data asynchronously and then use it as an input parameter for the next asynchronous operation
getData(function(a){  
    getMoreData(a, function(b){
        getMoreData(b, function(c){ 
            getMoreData(c, function(d){ 
                getMoreData(d, function(e){ 
                    ...
                });
            });
        });
    });
});
Copy the code

You can see that the above code looks terrible, with layers of nesting, and the code readability becomes very poor if complex logical judgments are added.

But if you use promise:

function getData() {
    return new Promise(function (resolve, reject) {
        resolve(1);
    });
}
function getMoreData(arg) {
    return new Promise(function (resolve, reject) {
        resolve(arg + 10);
    });
}
getData().then(function(a) { console.log(a); / / 1return getMoreData(a);
}).then(function (b) {
    console.log(b); // 11
})
Copy the code

Let me make this code a little bit cleaner

getData()
.then(a => getMoreData(a))
.then(b => console.log(b));
Copy the code
  • 2 A promise can be implemented to get or process a result after multiple requests are sent
// Do not operate until both data are returnedlet fs = require('fs');
fs.readFile('./1.txt'.'utf8'.function (err, data) {
    console.log(data);
})
fs.readFile('./2.txt'.'utf8'.function (err, data) {
    console.log(data);
})
Copy the code

This can be implemented using promises:

let fs = require('fs');
function read(url){
    return new Promise(function(resolve,reject){
        fs.readFile(url,'utf8'.function(err,data){
            if(err)reject(err);
            resolve(data);
        })
    })
}
Promise.all([read('1.txt'),read('2.txt')]).then(data=>{
    console.log(data);
},err=>{
    console.log(err);
});
Copy the code

Two, the promise principle realization

1. The simplest implementation can be realized based on the above application scenario, which finds that promise can have three states, namely pedding, depressing and Rejected.

This is a big pity, which is the Pending Promise state when the object instance is created. This is a big pity, which is the failure state of the Rejected Promise object instance

  • To construct aPromiseThe instance needs to be givenPromiseThe constructor passes in a function. The function passed in requires two parameters, both of which arefunctionType parameter. , respectively,resolveandreject.
  • PromiseThere are stillthenMethod,thenMethods are used to specifyPromiseDetermine the operation to be performed when the state of the object changes,resolveThe first function (ondepressing) will be performed.rejectExecute the second function (onRejected)
  • When the state becomesresolveCan no longer berejectAnd vice versa.

We can implement such a promise based on the above description

functionPromise(executor){// Executor executorlet self = this;
    self.status = 'pending'; // wait state self.value = undefined; Self. reason = undefined; // indicates a failed valuefunctionResolve (value){// Successful methodif(self.status === 'pending'){
            self.status = 'resolved'; self.value = value; }}functionReject (reason){// Failed methodif(self.status === 'pending'){
            self.status = 'rejected';
            self.reason = reason;
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFufiled,onRejected){
    let self = this;
    if(self.status === 'resolved'){
        onFufiled(self.value);
    }
    if(self.status === 'rejected'){
        onRejected(self.reason);
    }
}
module.exports = Promise;
Copy the code

Reference:

  1. Avoid callback hell in Node.js