最佳實踐
經過一段時間的使用,對於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 🌑。