I. Brief introduction of Promise


Promises are a solution to asynchronous programming: syntactically, promises are objects from which to obtain information about a set of actions; In its original sense, it is a contract that gives you a result over time.

Promise has three states:

  • Pending => Pending state
  • Fulfiled => Successful state
  • Rejected => Failed state

A callback function is created by passing a function as a data value to another function. The other function calls the passed function and calls it. Then the function successfully becomes a callback function.

// When num meets certain conditions, the function passed in is called the callback function
function fn1(a,fn){
  if(a > 15 && typeof fn == 'function'){
    fn(); / / execution fn
  }
}
fn1(16.function(){
  console.log('this is a callback');
})
Copy the code

In general, callbacks are nested at most one or two levels, when we encounter a lot of nested callbacks. The code becomes very complex and causes programming problems, which is called callback hell.

Promise was born with a halo to solve the problem:

  • The callback hell
  • Can solve asynchronous related problems
  • Support for multiple concurrent requests

Ii. Use promise


A promise is a constructor that has call, Reject, and resolve on its own, and then, catch, and so on on its prototype.

let p = new Promise((resolve,reject) = > {
  // Here are the methods for asynchronous operations
  setTimeout(() = > {
    console.log('Execution completed');
    resolve('It worked.');
  },2000)});Copy the code

The Promise constructor takes one argument:functionAnd the function takes two arguments:

  • Resolve: Callback function after asynchronous operation is successfully executed
  • Reject: Callback function when an asynchronous operation fails

thenThe use of chain operation

Essentially, the most praised part of promise is the state. Maintaining the state and passing the state so that the callback function can be called in time is simpler and more flexible than passing the callback function, so use promise like this:

p.then((data) = > {
  console.log(data);
})
.then((data) = > {
  console.log(data);
})
.then((data) = > {
  console.log(data);
});
Copy the code

Reject the use of the

Set the state of the Promise to Rejected so that we can capture it in THEN and execute the failed callback.

let p = new Promise((resolve,reject) = > {
  // Asynchronous operation
  setTimeout(() = > {
    let number = Math.ceil(Math.random() * 10); Ceil () returns an integer greater than or equal to the given number
    if(number <= 5){
      resolve(num);
    }else{
      reject('That's too big! '); }},2000);
});
p.then((data) = > {
  console.log('resolve',data);
},(err){
  console.log('reject',err);
})
Copy the code

The then method accepts two arguments, the first of which is a callback to resolve and the second to reject.

The use of the catch

We know that the Promise object has a catch method in addition to the THEN method, which is what the second argument to the then does, specifying the reject callback.

p.then((data) = > {
  console.log('resolve',data);
}).catch((err) = > {
  console.log('reject',err);
})
Copy the code

It has the same effect as the second argument in then; When the resolve callback throws an exception, the js code will not be stuck, but instead will be thrown into the catch method.

p.then((data) = > {
  console.log('resolve',data);
  console.log(hhz); // There is no HHZ variable
}).catch((err) = > {
  console.log('reject',err);
})
Copy the code

In the case above, the last output in then, HHZ, is undefined. If it is not a PROMISE, an error will be reported and the program will stop executing, but the promise will continue to execute, enter the catch, and explode the error.

All the usage of the

Promise’s All method provides the ability to execute asynchronous operations in parallel, with callbacks executed after all asynchronous operations have completed.

let p1 = new Promise( (resolve,reject) = >{
  // Asynchronous operation
})
let p2 = new Promise( (resolve,reject) = >{
  // Asynchronous operation
})
let p3 = new Promise( (resolve,reject) = >{
  // Asynchronous operation
})
let p = new Promise.all([p1,p2,p3])
p.then(() = > {
  // If three are successful, there is success
},() = > {
  // If you fail, you fail
})
Copy the code

With the all method, you can perform multiple asynchronous operations in parallel and process all returned data in a single callback.

The use of the race

The use of race is to set a timeout for an asynchronous operation and execute the corresponding operation after the timeout, with the following code:

// Request a video resource
function requestVideo(){
  let p = new Promise( (resolve,reject) = > {
    let video = new Video();
    video.onload = function(){
      resolve(video);
    }
    video.src = 'Video path'; });return p;
}

// The delay function is used to time the request
    function timeout(){
        var p = new Promise((resolve, reject) = > {
            setTimeout(() = > {
                reject('Image request timed out');
            }, 5000);
        });
        return p;
    }
    Promise.race([requestImg(), timeout()]).then((data) = >{
        console.log(data);
    }).catch((err) = > {
        console.log(err);
    });
Copy the code

The requestImg function asynchronously requests an image, and I wrote the address as “path to the image”, so it will definitely fail. The timeout function is an asynchronous operation with a delay of 5 seconds. We put the two functions that return the Promise object into race, and they race. If the image request is successful within 5 seconds, then the normal process is followed. If the image is not returned within 5 seconds, timeout wins and a catch message is displayed indicating that the image request has timed out.

Fulfill your promise

1. Implement successful and failed callbacks

To implement the function in the above code, is the most basic promise function. First, you need to create a constructor promise, which creates a promisel class that passes in an executor. The executor passes in two arguments: resolve and Reject. As I said, if you succeed, you don’t fail, and if you fail, you don’t succeed. So, by default, the call returns a success state on success and a failure state on failure. The code is as follows:

class Promise {
  constructor(executor){
    // The default state is wait
    this.status = 'pedding';
    this.value = undefined;
    this.reason = undefined;
    // Store the successful callback
    this.onResolveCallbacks = [];
    // Store the failed callback
    this.onRejectCallbacks = [];
    let resolve = (data) = > {
      // This points to an instance
      if(this.status === 'pedding') {this.value = data;
        this.status = 'resolved';
        this.onResolveCallback.forEach(fn= >fn()); }}let reject = (reason) = > {
            if(this.status === 'pending') {this.reason = reason;
                this.status = 'rejected';
                this.onRejectedCallbacks.forEach(fn= >fn()); }}try{// An exception may occur during execution
            executor(resolve,reject);
        }catch (e){
            reject(e);/ / promise failed}}}Copy the code

Article description:

Article a lot of learning from the following sponsors, the article is very good summary, so I want to save in their own side to facilitate query and recall. This is not complete, for full content and more exciting content, please visit the patron below.

Author: Manman Luo Xuan

Links: juejin. Cn/post / 684490…

Source: Nuggets

The copyright belongs to the author Manman Luo Xuan. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.