ES6 --- detailed explanation of promise basic usage (resolve, reject, then, catch)

Posted by rayfinkel2 on Sat, 22 Jan 2022 19:11:15 +0100

ES6 - Promise basic usage details

Promise Is a constructor. It has familiar methods such as all, reject and resolve,
There are also familiar methods such as then and catch on the prototype.
So, when starting a Promise, start with a new one:

let p = new Promise((resolve, reject)=> {
        setTimeout(()=> {
            resolve('Execution complete')
        }, 1000)
    })

Promise is a constructor that accepts a callback function as a parameter. The parameters of the callback function are resolve and reject. It represents the callback function after successful execution of asynchronous operation and the callback function after failure of asynchronous operation. In fact, the description of "success" and "failure" here is not accurate. According to the standard, resolve sets the state of promise to full file, and reject sets the state of promise to rejected. However, we can understand this at the beginning, and then study the concept in detail.

In the above code, we perform an asynchronous operation, that is, setTimeout. After 1 second, we output "execution completed" and call the resolve method.

Line of code, and "execution complete" will be output in 2 seconds. be careful! I just new an object. Without calling it, the function we passed in has been executed. This is a detail that needs attention. Therefore, when we use Promise, it is usually packaged in a function and run the function when necessary, such as:

function runAsync() {
    let p = new Promise((resolve, reject)=> {
        setTimeout(()=> {
            console.log('Execution complete');
            resolve(123);
        }, 2000)
    })
    return p;    
}

runAsync()

At this point, you should have a question: what is the use of wrapping such a function?

At the end of our wrapped function, we will return the Promise object {p, that is, by executing this function, we get a Promise object. There are then and catch methods on the Promise object, which can be used at this time. See the following code:

runAsync().then((result)=> {
    console.log(result);
    // Do other operations
})

The then method is called directly on the return of runAsync(), and then receives a parameter, which is a function and gets the parameters passed when we call resolve in runAsync. Running this code will output "execution complete" after 2 seconds, followed by "123".

At this time, you may have understood that the then method is the same as the callback function we usually write. Let's write the callback function directly. Why write Promise.

Indeed, in some simple scenarios, the callback function is enough, but in the current front-end environment and development, callback hell often occurs. You may need to continue the callback function in the callback function, which will be terrible. Promise brings us a better solution.

Promise has the advantage that you can continue to write the promise object and return it in the then method relay, and then continue to call then for callback operation.

Usage of chain operation


Take the following example to show how to use multi-layer callbacks:

function runAsync1() {
    var p = new Promise(function(resolve, reject) {
        setTimeout(function(){
            console.log('Execution complete 1');
            resolve(1);
        }, 2000)
    })
    return p;    
}

function runAsync2() {
    var p = new Promise(function(resolve, reject) {
        setTimeout(function(){
            console.log('Execution complete 2');
            resolve(2);
        }, 2000)
    })
    return p;    
}


function runAsync3() {
    var p = new Promise(function(resolve, reject) {
        setTimeout(function(){
            console.log('Execution completed 3');
            resolve(3);
        }, 2000)
    })
    return p;    
}

runAsync1().then(function(data) {
    console.log(data);
    return runAsync2();
}).then(function(data) {
    console.log(data);
    return runAsync3();
}).then(function(data) {
    console.log(data);
    return 'Direct return data'
}).then(function(data) {
    console.log(data);
})

In chain operation, when a Promise ends, you can continue to return a new Promise and continue to receive its returned resolve in the next then method.

In the then method, you can also directly return data instead of Promise object. You can receive data in the following then. See the last example above.

Usage of reject


When you finish resolve, you have to say reject. They are Promise's own methods. In short, the reject method returns an error message and sets the Promise state to rejected, as mentioned above.

Let's take a look at the specific implementation:

function getNumber() {
    var p = new Promise(function(resolve, reject) {
        setTimeout(function(){
            var num = Math.ceil(Math.random()*10);
            if(num<5) {
                resolve(num)
            } else {
                reject('The number is too big')
            }
        }, 2000)
    });
    return p;
}
getNumber()
    .then(
        function(data) {
            console.log('resolve')
            console.log(data);
        },
        function(reason) {
            console.log('reject')
            console.log(reason);            
        }
    )

We create a random number of 1-10, judge the size, and return different resolve and reject.

First, we can use the second parameter in the then method to receive the reject return value. If it is greater than 5, we will print out that the number is too large.

However, many people have contacted Promise before and know that there is also a chain operation method of catch. It can also be used to receive the information returned by reject. Look at the following code:

getNumber()
        .then(function(data) {
            console.log('resolve');
            console.log(data);
        })
        .catch(function(reason) {
            console.log('reject');
            console.log(reason); 
        })

If the number is greater than 5, reject 6 will be printed.

If you make an error in then, the program will not be interrupted, and the error message will be printed in catch:

getNumber()
        .then(function(data) {
            console.log('resolve');
            console.log(data);
            console.log(somedata);
        })
        .catch(function(reason) {
            console.log('reject');
            console.log(reason); // ReferenceError: somedata is not defined
        })

Topics: Javascript Front-end Vue.js