1. Understand promises

Promise is a solution to asynchronous programming, a new object in ES6 that delivers messages for asynchronous operations. It represents some event whose outcome will be known in the future (usually an asynchronous operation), and this event provides a uniform API for further processing.

Promise has the following two features:

(1) The state of Promise is not affected by the outside world. A Promise is a Promise made in the future. It has three states: Pending, Completed resolved, and failed. It represents an asynchronous operation, and only the result of the asynchronous operation can determine the current state. No other operation can change this state.

(2) Once a Promise changes from a wait state to another state, it can never change to another state. That is, when the status changes from Pending to Resolved or Rejected, the status cannot be changed.

new Promise((resolve, reject) = > {
    resolve('resolve')
    reject('reject') // This reject is invalid
})
Copy the code

When we construct a Promise, the code inside the constructor executes immediately:

new Promise((resolve, reject) = > {
    console.log(1);
    resolve('resolve')})console.log(2);
Copy the code

Chain call for Promise:

new Promise(function(resolve, reject){
    resolve(1);
}).then(function(data){
    console.log(data);
    return 2; // wrap as promise.resolve (2)
}).then(function(data){
    console.log(data);
}).catch(function(err){
    console.log(err);
})
Copy the code

Promise solves the problem of callback hell nicely, allowing code to be more concise and elegant.

Promises also have some drawbacks :(1) they are immediately executed once they are created and cannot be cancelled midway; (2) Errors need to be caught by callback functions.

Write a simple Promise by hand

First, create three constants that represent the state:

const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
Copy the code

To frame a constructor:

function myPromise(fn) { // A function is passed in
    // Define a constant that to cache the current this object
    const that = this;
    // The initial state is pending
    that.status = PENDING;
    // Define a variable to hold the value passed in resolve or reject
    that.param = null;
    // Define two arrays to record functions that will be executed after an asynchronous operation.
    that.resolvedCallBacks = []; // The function to execute after the status transition succeeds
    that.rejectedCallBacks = []; // Function executed after state transition fails
    // Define resolve
    function resolve() {}// Define reject
    function reject() {}// Execute the fn function
    fn();
}
Copy the code

Here’s how to improve the resolve and reject functions:

    // Define resolve
    function resolve(param) {
        // This command is executed only when the state is initial
        if (that.status === PENDING) {
            that.status = RESOLVED; // The status changes to success after execution
            that.param = param; // Record the parameters passed in
            // Iterate over the callback function and execute
            that.resolvedCallBacks.map(function(callback){ callback && callback(that.param); }}})// Define reject
    function reject(param) {
        // This command is executed only when the state is initial
        if (that.status === PENDING) {
            that.status = REJECTED; // The state changes to failed after execution
            that.param = param; // Record the parameters passed in
            // Iterate over the callback function and execute
            that.resolvedCallBacks.map(function(callback){ callback && callback(that.param); }}})Copy the code

When the fn function is executed, resolve and reject are passed as arguments, and reject is executed when an error is caught

    // Execute the fn function
    try {
        fn(resolve, reject);
    } catch(e) {
        reject(e);
    }
Copy the code

Then we implement the then function:

// Then function has two parameters ondepressing, onRejected
// Ondepressing will be called as a callback function when the current instance state becomes successful
// onRejected is called as a callback function when the current instance state becomes failed
myPromise.prototype.then = function(onFulfilled, onRejected) {
    const that = this;
    // When the state is initial, the corresponding function is saved to the corresponding callback function array
    if (that.status === PENDING) {
        that.resolvedCallBacks.push(onFulfilled);
        that.rejectedCallBacks.push(onRejected);
    }
    // When the state is successful, ondepressing will be performed
    if (that.status === RESOLVED) {
        onFulfilled(that.param);
    }
    // When the state is successful, ondepressing will be performed
    if(that.status === REJECTED) { onRejected(that.param); }}Copy the code

The above is a simple version of the Promise implementation, and finally a simple run:

new myPromise(function(resolve, reject){
    resolve(1);
    // reject(2);
}).then(function(data) {
    console.log(data);
}, function(err) {
    console.log(err);
})
Copy the code