async/await的理解
发表于:2022-03-27 | 分类: 前端
字数统计: 968 | 阅读时长: 4分钟 | 阅读量:

async/await的理解

遇到个五连回调的代码,真的是地狱级拷打,用async await进行了一波改写,顿时神清气爽,总结一下。
顾名思义,async是异步的简写,awaitasync await的简写。所以async就是用于声明一个function是异步的,而await就是用来等待这个异步方法执行完成的。另外,规定await只能在async中使用。

async作用及工作原理

先看下async是怎么处理返回值的

1
2
3
4
5
6
async function testAsync() {
return "hello world";
}

const result = testAsync();
console.log(result);// Promise {'hello world'}

可见,async返回一个Promise对象。如果在async函数中直接return一个值,那么async会把这个值通过Promise.resolve()封装成Promise对象。Promise的特点——无等待,所以在没有使用await的情况下,async会立即执行,不会阻塞后面的代码。

await在等谁呢?

原以为,await在等待async的函数完成,等async的讯息。看了文档后,await等待的其实是一个表达式,这个表达式的计算结果是Promise对象或者其它值。
await不仅仅用于等Promise对象,它可以等任意表达式的结果,所以await是可以接普通函数的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getValue() {
return 123;
}

async function testAsync() {
return Promise.resolve("hello world");
}

async function test() {
const v1 = await getValue();
const v2 = await testAsync();
console.log(v1, v2);// 123 hello world
}

test();

await等到结果之后

返回Promise对象的处理结果,如果等待的不是Promise对象,则返回值本身。
await会在暂停async函数,等待Promise处理完成。
如果Promise正常处理,则回调的resolve函数参数作为await的值,继续执行async函数。
如果Promise处理异常,await会把Promise的异常原因抛出。

为啥要使用async/await

反正都是处理Promise对象,为啥不直接用.then()呢?用setTimeout模拟耗时的异步操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    function mockApi() {
return new Promise((resolve) => {
setTimeout(() => resolve("hello world"), 1000);
});
}

// then写法
mockApi().then(v => {
console.log("then", v);
})

// async/await写法
async function test() {
const v = await mockApi();
console.log(v);
}

test();

async/await反而要多写一点代码,繁重的工作雪上加霜了。😂😂😂😂😂
不要着急,脱裤子肯定不是为了…
单一的Promise链并不能发现async/await的妙用😏,当遇到多个Promise组成的then链时,你会发现async/await就是救世主。
试试看,一个业务处理分成多个步骤,每一步都是异步 的,而且每一步都依赖前一步的结果。
setTimeout受累一下😙😙😙

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* 传入参数value,表示这个函数执行的时间
* 执行结果增加1000,用于下一步
* @param {*} value 时间
* @returns 时间+1000ms
*/
function mockApi(value) {
return new Promise((resolve) => {
setTimeout(() => resolve(value + 1000), value);
});
}

function step1(value) {
console.log(`step1 with ${value}`);
return mockApi(value);
}

function step2(value) {
console.log(`step2 with ${value}`);
return mockApi(value);
}

function step3(value) {
console.log(`step3 with ${value}`);
return mockApi(value);
}

// then写法

function testThen() {
console.time("testThen");
const time1 = 300;
step1(time1).then((time2) => {
step2(time2).then((time3) => {
step3(time3).then((result) => {
console.log(`result is ${result}`); // 我已经晕了😵😵😵😵
console.timeEnd("testThen");
});
});
});
}

testThen();
// step1 with 300
// step2 with 1300
// step3 with 2300
// result is 3300
// testThen: 3921.948ms

// async/await写法
async function testAsync() {
console.time("testAsync");
const time1 = 300;
const time2 = await step1(time1);
const time2 = await step3(time1);
const result = await step3(time1);
console.log(`result is ${result}`); // YYDS
console.timeEnd("testAsync");
}

testAsync();

async/await有多清晰,不用多说了吧。

附庸风雅😳😳😳

梅花引 荆溪阻雪 蒋捷

白鸥问我泊孤舟

是身留?是心留?

心若留时,何事锁眉头?

风拍小帘灯晕舞

对闲影,冷清清,忆旧游。

旧游旧游今在不?

花外楼,柳下舟。

梦也梦也,梦不到,寒水空流。

漠漠黄云,湿透木棉裘。

都道无人愁似我

今夜雪,有梅花,似我愁。

上一篇:
css学习一
下一篇:
JS循环总结