1. async 和 await 在幹什麼
注意 :await只能出現在async聲明的函數中
async function testAsync() {
return "hello async";
}
const result = testAsync();
console.log(result);
打印結果
c:\var\test> node --harmony_async_await .
Promise { 'hello async' }
看到輸出就恍然大悟了——輸出的是一個 Promise 對象。
async 函數返回的是一個 Promise 對象,所以在最外層不能用 await 獲取其返回值的情況下,我們當然應該用原來的方式:then()
鏈來處理這個 Promise 對象,就像這樣
testAsync().then(data => {
console.log(data)
})
2. await 到底在等待着什麼?
如果它等到的不是一個 Promise 對象,那 await 表達式的運算結果就是它等到的東西。
如果它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞後面的代碼,等着 Promise 對象 resolve,然後得到 resolve 的值,作爲 await 表達式的運算結果。
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
var data = v1+':'+v2+':'+'666';
return data ;
}
test().then(v => {
console.log(v)
}).catch((error) => {
console.log(error)
});
3. async/await 的優勢在於處理 then 鏈
單一的 Promise 鏈並不能發現 async/await 的優勢,但是,如果需要處理由多個 Promise 組成的 then 鏈的時候,優勢就能體現出來了(很有意思,Promise 通過 then 鏈來解決多層回調的問題,現在又用 async/await 來進一步優化它)。
假設一個業務,分多個步驟完成,每個步驟都是異步的,而且依賴於上一個步驟的結果。我們仍然用 setTimeout
來模擬異步操作:
/**
* 傳入參數 n,表示這個函數執行的時間(毫秒)
* 執行的結果是 n + 200,這個值將用於下一步驟
*/
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n + 200), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(n) {
console.log(`step2 with ${n}`);
return takeLongTime(n);
}
function step3(n) {
console.log(`step3 with ${n}`);
return takeLongTime(n);
}
用async/await來寫:
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time1, time2);
const result = await step3(time1, time2, time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 800 = 300 + 500
// step3 with 1800 = 300 + 500 + 1000
// result is 2000
// doIt: 2907.387ms
例如現在把需求改一下:仍然是三個步驟,但每一個步驟都需要之前每個步驟的結果。
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime(m + n);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime(k + m + n);
}
用async/await來寫:
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time1, time2);
const result = await step3(time1, time2, time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 800 = 300 + 500
// step3 with 1800 = 300 + 500 + 1000
// result is 2000
// doIt: 2907.387ms