Home > Web Front-end > JS Tutorial > Understand promise, async, await

Understand promise, async, await

hzc
Release: 2020-07-04 09:50:13
forward
1921 people have browsed it

The previous article mainly talked about synchronization and asynchronousness, the 'execution stack', 'message queue', as well as 'macro tasks' and 'micro tasks' derived from each of them. If you understand these concepts If you don’t know much about it, you can go to this link:

https://www.jianshu.com/p/61e7844e68d8

Both macro tasks and micro tasks are asynchronous, including ajax requests and timing. We have a preliminary understanding of promise and know that it is a way to solve asynchronous problems. So what are the methods we commonly use?

Because it involves a lot of knowledge points, this article Mainly let’s talk about callback functions and promises:

1. Callback function

先上代码:
function f2() {
    console.log('2222')
}
function f1(callback){
    console.log('111')
  setTimeout(function () {
    callback(); 
  }, 5000);
  console.log('3333')
}
f1(f2);

先看下打印值是:
111
3333
五秒后2222
Copy after login

is equivalent to the fact that after the main thread has finished executing, the f2 function will be called through the callback function. This Nothing wrong with it. But look at the following example:

现在我们读取一个文件,fileReader就是一个异步请求

// 这个异步请求就是通过回调函数的方式获取的

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file, 'utf-8',function(err, data){
    if(err){
        console.log(err)
    } else {
        console.log(data)
    }
})
Copy after login

It looks very good now, but if there is an error in file upload, we still have to make a judgment in the callback. If we finish reading this file, we have to read multiple Where are the files? Should it be written like this:

读取完文件1之后再接着读取文件2、3

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file1, 'utf-8',function(err1, data1){
    if(err1){
        console.log(err1)
    } else {
        console.log(data1)
    }
    reader.readAsText(file2, 'utf-8',function(err2, data2){
        if(err2){
            console.log(err2)
        } else {
            console.log(data2)
        }
        reader.readAsText(file3, 'utf-8',function(err3, data3){
            if(err3){
                console.log(err3)
            } else {
                console.log(data3)
            }
        })
    })
})
Copy after login

Writing this way can achieve the requirements, but the readability of this code is relatively poor and it does not look so elegant, which is what we often call 'callback hell'. So how to crack this nested callback? ES6 provides us with promises:

2. Promise

First, let’s understand what a promise is literally? Promise can be translated into commitment and guarantee. You can understand this place as:

My girlfriend asked me to do something. Although I haven’t finished it yet, I promise that there will be a result for you. Success (fulfiled) or failure (rejected), and a waiting state (pending).

还是先上例子

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000) // 成功以后这个resolve会把成功的结果捕捉到
        // reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})

promise.then(res => {
    console.log(res) // then里面第一个参数就能拿到捕捉到的成功结果
}, err =>{
    console.log(res)// then里面第二个参数就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)
Copy after login

1. Then chain operation

The then method of the Promise object returns a new Promise object, so the then method can be called through the chain.

Thethen method receives two functions as parameters. The first parameter is the callback when Promise is executed successfully, and the second parameter is the callback when Promise fails to execute. The above example makes it very clear. The two parameters capture the failed callback.

Only one of the two functions will be called. How to understand this sentence?
Your girlfriend asks you to make tomato and egg soup. You either do it or you don’t and order takeout. There is definitely no third option.

The return value of the function will be used to create the Promise object returned by then. How should this sentence be understood? Still the above example:

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000)
    }, 1000)
    console.log(1111)
})
promise.then(res => {
    console.log(res) // 这个地方会打印捕捉到的2000
    return res + 1000 // 这个函数的返回值,返回的就是这个promise对象捕捉到的成功的值
}).then(res => {
    console.log(res) //这个地方打印的就是上一个promise对象return的值
})

所以打印顺序应该是:

1111
2000
3000
Copy after login

Just now we saw that then accepts two parameters, one is a successful callback and the other is a failed callback. It doesn’t seem that elegant. In addition to then, promise also provides a catch method. :

2. Catch capture operation

This catch is specifically designed to capture error callbacks. Let’s look at the example first:

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})
promise.catch(res => {
    console.log(res) // catch里面就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)
Copy after login

In addition to then and catch, promise also has We also use the two syntaxes, all and race, briefly:

3, all

Now we have such a requirement. There are three interfaces A, B, and C. Three are required. After all interfaces are successful, the fourth request can be initiated. How to implement it?

Chained calls

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
}).then(res => {
    let getInfoB = new Promise((resolve, reject) => {
        console.log('小B开始执行了')
        resolve()
    }).then(res => {
        let getInfoC = new Promise((resolve, reject) => {
            console.log('小C开始执行了')
            resolve()
        }).then(res => {
            console.log('全都执行完了!')
        })
    })
})
Copy after login

It’s one layer inside another, it doesn’t seem so elegant

all

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    resolve()
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    resolve()
})
Promise.all([getInfoA, getInfoB, getInfoC]).then(res => {
   console.log('全都执行完了!')
})
Copy after login

Receives an array composed of Promise objects as parameters , when the status of all Promise objects in this array becomes resolved or rejected, it will call the then method. So perfect, so elegant.

4, race

Now there is another requirement, which is also interface A, B, C. As long as one of them responds, I can adjust interface D. So how to implement it?

1. Traditional method

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
}).then(res =>{
    console.log(res)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
}).then(res =>{
    console.log(res)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
}).then(res =>{
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快
Copy after login

This method has to be written three times, and it doesn’t seem to be that elegant. Let’s take a look at how to write race?

2, race

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
})
Promise.race([getInfoA, getInfoB, getInfoC]).then(res => {
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快
Copy after login

Similar to Promise.all, Promise.race takes an array composed of Promise objects as parameters. The difference is that as long as one of the Promise objects in the array When the Promsie status changes to resolved or rejected, the .then method can be called.

Promise is a method used by ES6 to solve asynchronous problems. It is now widely used. For example, axios, which we often use, is encapsulated with promise and is very convenient to use.

In addition to promises, ES6 also provides us with the ultimate tricks async and await. Because these two knowledge blocks are relatively large, we are going to talk about them in the next article.

Personal WeChat public account: If Jerry has something to say, he usually posts some technical articles and reading notes. Welcome to communicate.

Recommended tutorial: "JS Tutorial"

The above is the detailed content of Understand promise, async, await. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:jianshu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template