I Promise.

  • Promises are a means of implementing asynchronous code that stores some outcome that will happen in the future. The Promise method receives a function parameter handler, which a New Promise instance executes immediately. The function handler receives two method arguments, resolve and Reject, representing successful and failed callback functions, respectively. Usage:
const p = new Promise((resolve,reject) = > {
    setTimeout(function(){
        resolve('success')},200);
});
p.then(res= > console.log(res)); / / success
Copy the code
  • The then method of a Promise, which returns a new Promise instance, can therefore support chained calls. Usage:
const p = new Promise((resolve,reject) = > {
    setTimeout(function(){
        resolve('success')},200);
});
p.then(res= > {
    return res+1;
}).then(data= > console.log(data)); 1 / / success
Copy the code
  • If the THEN method returns a new promise instance, the chain call after the THEN method waits for the new promise to complete and passes the result of the new promise as an argument to the callback function of the next THEN method. Such as:
const p = new Promise((resolve,reject) = > {
    setTimeout(function(){
        resolve('success')},200);
});
p.then(res= > {
    return new Promise((resolve,reject) = >{
        resolve(123);
    });
}).then(data= > console.log(data)); / / 123
Copy the code

In this example, the first THEN method of P returns a new Promise instance, and when the new Promise instance executes, 123 is passed into the callback function of the next THEN method, printing 123.

The above is the basic function of Promise, we write a Promise, convenient to understand the Promise principle.

Write a Promise

1. Implement promises through classes :(recommend!)

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class myPromise{
    constructor(handle) {
        this.resolveCallCack = []; // Store the callback function on success
        this.rejectCallCack = []; // Store the callback function when it fails
        this.value = undefined;
        this.err = undefined;
        this.status = PENDING; // State of the promise

        let resolve = (data) = > {
            if(this.status ! == PENDING)return;
            this.status = FULFILLED;
            this.value = data;
            this.resolveCallCack.forEach(fn= > {
                fn(this.value);
            });
        }

        let reject = (err) = > {
            if(this.status ! == PENDING)return;
            this.status = REJECTED;
            this.err = err;
            this.rejectCallCack.forEach(fn= >{ fn(tthis.err); })}if(handle instanceof Function){ handle(resolve,reject); }}then(resolveNext,rejectNext) {
        let that = this;
        return new Promise((resolve,reject) = >{
            switch(this.status){
                case PENDING:
                    this.resolveCallCack.push(resolveNext);
                    this.rejectCallCack.push(resolveNext);
                    break;
                case FULFILLED:
                    resolveNext(this.value);
                    break;
                case REJECTED:
                    rejectNext(this.err);
                    break; }}}})var a = new myPromise(function(resolve,rejected) {
    setTimeout(function(){
        resolve("Success");
    },2000);
}).then(data= > {
    console.log(data);
})const PENDING = 'pending';

Copy the code

Conclusion:

  • Disadvantages: When a new promise instance is returned in the then method of the handwritten myPromise, the execution result is different from ES6 promise and needs to be improved.

2. Realize the promise function by defining myPromise function:

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function myPromise(handle){
    var self = this; // Save a copy of this to prevent this method from being corrupted.
    self.status = PENDING;
    self.value = ' ';
    self.reson = ' ';
    self.resolvedCallback = [];
    self.rejectedCallback = [];

    function resolve(data){
        if(self.status ! == PENDING)return;
        self.status = FULFILLED;
        self.value = data;
        self.resolvedCallback.forEach(fn= > {
            fn(self.value);
        });
    }
    function reject(data){
        if(self.status ! == PENDING)return;
        self.status = REJECTED;
        self.reson = data;
        self.rejectedCallback.forEach(fn= > {
            fn(self.reson);
        });
    }

    try{
        handle(resolve,reject);
    }catch(e){
        reject(e)
    }
}

myPromise.prototype.then = function(resolveNext,rejectNext){
    var that = this;
    return new myPromise((resolve,reject) = > {
        switch(that.status){
            case PENDING:
                that.resolvedCallback.push(resolveNext);
                that.rejectedCallback.push(rejectNext);
                break;
            case FULFILLED:
                resolveNext(that.value);
                break;
            case REJECTED:
                rejectNext(that.reson);
                break; }}); } myPromise.all =function(arr){
    return new myPromise((resolve,reject) = >{
        var res = [];
        arr.forEach(item= > {
            item.then(data= > {
                res.push(data);
                if(res.length === arr.length){ resolve(res); }},err= >{ reject(err); })}); }); }//// tests the myPromise method
var obj = new myPromise(function(resolve,reject){
     setTimeout(function(){
         resolve(2);
     },0);
}).then((data) = >{
     console.log(data);
})

var obj2 = new myPromise(function(resolve,reject){
     setTimeout(function(){
         resolve(3);
     },0);
}).then((data) = >{
     console.log(data);
})

// Test the myPromise.all method
var obj = new myPromise(function(resolve,reject){
    setTimeout(function(){
        resolve(2);
    },0);
})

var obj2 = new myPromise(function(resolve,reject){
    setTimeout(function(){
        resolve(3);
    },0);
})
var myall = myPromise.all([obj,obj2]).then(data= > {
    console.log("resolve", data);
},err= > {
    console.log(err);
});
console.log(myall);
Copy the code

Conclusion: It is recommended to implement a promise through a class. If you implement a promise using a function, save a copy of this to prevent subsequent methods from accessing this.