async/await的正确使用
最佳实践
经过一段时间的使用,对于async/await
的正确使用,我总结了一下几点:
-
必须使用
try...catch
。确保正确的流程控制。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// resolve
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ state: 1 }), 1000);
});
}
// reject
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => reject({ error: 2 }), 1000);
});
}
async function hello() {
let data = await getData();
console.log(data.state);
}
async function hello() {
try {
let data = await getData();
console.log(data.state);
} catch (e) {
console.log(e);
let data = {};
}
}
hello();如果
await
后面的promise
返回的是reject
,那么下面的同步代码不会执行。所以必须使用try...catch
,如果出现这种情况,
会进入catch
,执行错误处理代码。 -
多重嵌套时,内层的
try...catch
必须有返回值,且catch
中的返回值是Promise.reject
。返回值是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
25
26
27
28
29
30
31
32
33// resolve
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ state: 1 }), 1000);
});
}
// reject
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => reject({ error: 2 }), 1000);
});
}
async function hello() {
try {
return await getData();
} catch (e) {
console.log(`${e} --- hello catch`);
return Promise.reject(e);
// return Promise.resolve(e)
}
}
async function world() {
try {
// 不会执行
data = await hello();
} catch (e) {
data = {};
console.log(`${e} --- world catch`);
}
}
world();world
使用异步方式调用了hello
,如果hello
中的getData
方法抛出了错误,会进入hello
里的catch
,则catch
中也必须有返回值,否则,将不会进入world
中的catch
,而是继续执行try
里面的代码;如果使用了Promise.resolve
返回内容或者返回内容不是Promise
,就也是执行try
里面的代码;只用返回的结果是Promise
且为Promise.reject
,才会正常的进入world
中的catch
。 -
vue 的生命周期是独立的,不会受到异步函数的影响。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20export default {
data() {
return {
data: null
};
},
async created() {
this.data = await this.getData();
},
mounted() {
console.log(this.data);
},
methods: {
getData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ state: 1 }), 1000);
});
}
}
};我们知道
created
函数会早于mounted
被调用,但是mounted
并不会等待created
中的异步函数,vue
的生命周期只跟其内部的执行流程有关,不受外界的影响。
总结
就如我一开始所说,async/await
并不是什么新的技术,而只是语法糖。
但是,如果要替代现在的promise
,特别是在多人团队中推广,我还是建议先去学习一下语法,尤其是异常处理和多层嵌套下向外抛出异常,不然,….说多了都是坑 😂。
这篇文章只是讲了async/await
的具体实践,如果你想了解promise
和async/await
的实现原理,请移步Promise实现原理 🌑 从Promise到async/await 🌑。