0%

js | async/await

这是一个非常重要的特性。

在看这篇之前,请先看


参考资料



注意点


  • await 只能在 async 标记的函数内部使用,单独使用会触发 Syntax error

使用


async/await 最大的特点就是把异步调用写成同步形式。

异步调用的同步写法

之前的例子。

1
2
3
4
5
function test(){
let res = axios.get("https://www.baidu.com")
console.log(res)
}
test()

输出

Promise { <pending> }

如果想要获取返回值,可以这样写。

1
2
3
4
5
6
function test(){
axios.get("https://www.baidu.com").then((res) =>{
console.log(res)
})
}
test()

但是,这样不够优雅,那么有没有可能写成第一种同步形式的异步调用。

1
2
3
4
5
6
7
async function test() {
let res = await axios.get("https://www.baidu.com")
console.log(res.data)
}

test()
console.log(123)

输出

1
2
123
res.data

借助 async/await 就可以轻松做到。

异步中含有异步

await 会把方法中的顺序方法全部执行完,然后返回,如果有异步方法,则异步方法是自行执行。

怎么理解上面的话呢?

1
2
3
4
5
6
7
8
async function test() {
console.log(1)
let res = await axios.get("https://www.baidu.com")
console.log(2)
}

test()
console.log(3)

上面这个会输出

1
2
3
1
3
2

这是因为,test 中会先把同步的代码执行完,然后遇到 await 之后,会让出当前进程,先让主进程运行下去,等异步调用返回后,再接着回来继续执行。

你可以简单的理解成, 遇到 await 会让出当前进程。另外,根据例子举一个不恰当的比喻,一个使用 await 修饰的函数,可以看作是一个整体进程,是顺序执行的,如上面 test() 的内部,但是,外面,testconsole 是两个独立的方法。

如果,我就是想执行这个顺序呢。

1
2
3
1
2
3

那么可以这样写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function test() {
return new Promise(async (resolve)=>{
console.log(1)
let res = await axios.get("https://www.baidu.com")
console.log(2)
resolve("aaa")
})
}

async function t(){
let a = await test()
console.log(a)
console.log(3)
}

t()

输出

1
2
3
4
1
2
aaa
3

另外上面的代码可以修改成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function test() {
console.log(1)
let res = await axios.get("https://www.baidu.com")
console.log(2)
return res
}

async function t() {
let a = await test()
console.log(a)
console.log(3)
}

t()

输出的顺序是一样的。

那么,是不是所有的异步回调都可以写成上面的方法?

答案是否定的,比如,异步函数中存在回调函数。

sql 为例。

其方法是

1
2
db.query(sql, (error: any, results: any) => {
})

里面的参数就有一个回调函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import {mysqlConfig} from "./config/config"
import mysql from "mysql"

let db = mysql.createConnection(mysqlConfig);
db.connect()

let sql = "select * from config_tickings where is_chain = 1;"

async function test() {
console.log(1)
db.query(sql, (err, res) => {
return "aaa";
})
console.log(2)
}

async function t() {
let a = await test()
console.log(a)
console.log(3)
}

t()

输出的是

1
2
3
4
1
2
undefined
3

如果想要获取 aaa 那么,就得使用 promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {mysqlConfig} from "./config/config"
import mysql from "mysql"

let db = mysql.createConnection(mysqlConfig);
db.connect()

let sql = "select * from config_tickings where is_chain = 1;"

async function test() {
console.log(1)
return new Promise((resolve) =>{
db.query(sql, (err, res) => {
resolve("aaa")
})
})
}

async function t() {
let a = await test()
console.log(a)
console.log(3)
}

t()

输出

1
2
3
1
aaa
3
请我喝杯咖啡吧~