Some knowledge points of Promise object

Promise object

1. Basic usage

Promise object is a constructor used to generate promise instances

var promise  = new Promise(function(resolve,reject){
    //...some code
})

Promise constructor accepts a function as a parameter. The two parameters of the function are resolve and reject. They are two functions provided by the JS engine without configuration.

  • resolve: callback function after successful execution of asynchronous operation

  • reject: callback function after asynchronous operation fails

After the Promise instance is generated, you can use the then method to specify the callback functions of Resolved state and Rejected state respectively. The then method can accept two parameters, the first corresponding to the callback of resolve and the second corresponding to the callback of reject.

function timeout(ms){
return new Promise((resolve,reject) => {
    setTimeout(resolve,ms,'done');
})
}
timeout(100).then((value) => {
    console.log(value);
})

In the above code, the timeout method returns a Promise instance, representing the result that will not occur for a period of time. After the specified time (ms), the state of Promise instance changes to Resolved, and the callback function bound by then method will be triggered.

Promise will be executed immediately after it is created.

The callback function specified by the then method will not be executed until all synchronization tasks in the current script are completed

let promise = new Promise(function(resolve,reject){
    console.log('Promise');
    resolve();
})
promise.then(function(){
    console.log('Resolved');
})
console.log('Hi!');
//Promise
//Hi!
//Resolved

If you don't understand this example, it's recommended to learn about synchronous tasks, asynchronous tasks, macro tasks, micro tasks, etc Portal

eg1: load pictures asynchronously

Promise is used to wrap an asynchronous operation of image loading. If the loading is successful, the resolve method is called. Otherwise, the reject method is called and an error parameter is passed in.

function loadImgeAsync(url){
	return new Promise(function(resolve,reject){
	var image= new Imge();
     //Load successfully executed
     image.onload = function(){
         resolve(image);
	}
    //Load failed execution
     image.onerror = function(){
         reject(new Error('Could not load image at ' + url));
     }
     image.url = url;
    })
}

If the resolve function and reject function are called with parameters, these parameters are passed to the callback function. The parameter of the reject function is usually an instance of the Error object, indicating the Error thrown; In addition to the normal value, the parameter of the resolve function may also be another Promise instance.

var p1 = new Promise(function (resolve,reject){
    //...
})
var p2 = new Promise(function (resolve,reject){
    //...
    resolve(p1);
})

The resolve method of p2 takes p1 as a parameter, that is, the result of an asynchronous operation is to return another asynchronous operation

At this time, the state of p1 will be passed to p2, that is, the state of p1 will determine the state of p2. If the state of p1 is pending, the callback function of p2 will wait for the state of p1 to change; If the status of p1 is Resolved or Rejected, the callback function of p2 will be executed immediately.

var p1 = new Promise(function(resolve,reeject){
    setTimeout(() => reject(new Error('fail')),3000);
})
var p2 = new Promise(function (resolve,reject){
    setTimeout( () => resolve(p2) , 1000);
})
p2
	.then(result => console.log(result));
	.catch(error = > console.log(error));

In the above code, p1 is a Promise, which becomes rejected after 3s, the state of p2 changes after 1s, and the resolve method returns p1,. Since another Promise is returned, the p2 state is invalid. p1 determines p2. After another 2s, p1 becomes rejected, triggering the callback function bound by catch.

2.Promise.prototype.then()

The then method is defined on the Promise.prototype of the prototype object. Its function is to add a callback function when the state changes for the Promise instance. The first parameter is the callback function in Resolved state, and the second parameter is the callback function in Reject state.

The then method returns a new Promise object whose state is determined by the execution result of the callback function

  • If the result returned by the callback function is an attribute of non Promise type, the status of the object is successful, and the successful value is the return value of the callback function (undefined if there is no return)

  • If the result returned by the callback function is the Promise state returned inside the Promise object, it determines the Promise state returned by the then method. The internal Promise success value is the success value (or failure) of the new Promise

  • The thrown error status is failure, and the value of the error is throw (the throw operator is used to throw a user-defined error at any time, and the type of value is unlimited.)

I don't know then, the return value of catch. Look at this blog, Portal

const p = new Promise((resolve,reject) => {
            setTimeout(()=>{
                resolve('user data');
            } , 0)
        })
        const result = p.then(value => {
            console.log(value);
            return '123'
        } , reason => {
            console.error(reason);
        })
        console.log(result);

Chain writing can be used. (to solve the callback hell problem)

getJSON("/posts.json").then(function (json){
    return json.post;
}).then(function(post){
    //...
})

The above code specifies two callback functions in turn using the then method. After the first callback function is completed, the returned result will be passed into the second callback function as a parameter.

Chained then can specify a set of callback functions to be called in order. The previous callback function may return a Promise object, and the latter callback function will wait for the state of the Promise object to change before being called.

3.Promise.prototype.catch()

Is the alias of. Then (null, rejection) (the syntax sugar of the then method, and the return value is the same as then), which is used to specify the callback function when an error occurs.

getJSON('/post.json').then(function(posts){
    //...
}).catch(function(error){
    //Error occurred when processing getJSON and the previous callback function
    console.log('An error occurred!',error);
})

The getJSON method returns a Promise object. If the state of the object changes to Resolved, the callback function specified by the then method will be called; If an asynchronous operation throws an error, the state changes to Rejected, and then calls the callback function specified by the catch method to handle this error. In addition, if the callback function specified by the then method throws an error during operation, it will also be caught by catch.

4.Promise.all()

Wrap multiple Promise instances into a new Promise instance. Receive an array (must have an Iterator interface, and each returned member is a Promise instance)

var p = Promise.all([p1 , p2 , p3]);

The state of p is determined by p1, p2 and p3, which can be divided into two cases:

  1. The state of p1, p2 and p3 will become fully, and the state of p will become fully. At this time, the return values of p1, p2 and p3 form an array and are passed to the callback function of p.
  2. As long as one of p1, p2 and p3 is Rejected, the state of p becomes Rejected. At this time, the return value of the first Rejected instance will be passed to the callback function of p
    The following are two examples about the then,catch return value and Promise.all() method. Note the differences between the two examples (this example comes from Ruan Yifeng's ES6 book)
const p1 = new Promise((resolve,reject) => {
    resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve,reject) => {
    throw new Error('Something went wrong!')
})
.then(result => result)
.catch(e => e);

Promise.all([p1 , p2])
.then(result => console.log(result))
.catch(e => console.log(e));

//["hello",Error: error!]
//What is the status of P1 and P2? What is the value? Why is the input like this?
  1. p1: the Promise object state changes to resolved. The callback function that triggers the binding of the then method passes in the parameter 'hello'; The then method returns a new Promise instance. Since the return value of the callback function is a string (non Promise object), the state of the new Promise object is resolved and the value is' hello ', and the new Promise object is assigned to p1
  2. p2: the error thrown when the Promise object state changes to reject will be captured by the catch method, and the parameter is the error instance; The catch method is the syntax sugar of the then method. Since the return value of the callback function is the error object (non Promise object), the status of the returned Promise object is resolved and the value is the error instance. Assign the Promise object returned by catch to p2
  3. Promise.all() P1 and P2 are in the state of resolved. The new promise instance generated by the wrapper is in the state of resolved. The parameters passed in by the callback function that triggers the then method binding are an array of parameters composed of return values, so it prints ["hello", Error: Error!]
const p1 = new Promise((resolve,reject) => {
    resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve,reject) => {
    throw new Error('Something went wrong!')
})
.then(result => result)

Promise.all([p1 , p2])
.then(result => console.log(result))
.catch(e => console.log(e));
//Error: error!
  1. p1: same as above
  2. p2: the state of the Promise object changes to reject. Since the callback function is not bound with catch, the error thrown is not captured. The state of the Promise instance changes to rejected
  3. Promise.all() if the status of p2 is rejected, the callback function bound to catch will be triggered. The parameter passed in is the return value of p2 (Error instance), so Error: Error is printed!

Keywords: Javascript Front-end ECMAScript

Added by thegreatdanton on Wed, 10 Nov 2021 02:21:29 +0200