天天看點

從 async 和 await 函數傳回值說原理

從 async 和 await 函數傳回值說原理

async 和 await 如何工作,如何正确的使用 async 和 await 。

什麼是 async 和 await ?

簡單來說,它們是 promise 嵌套的文法糖,來看一個執行個體:

async function helloAsync() {
    const result = await new Promise((resolve) =>
        setTimeout(() => resolve("Hello"))
    );
    console.log(result); // Hello
}


helloAsync();      

運作上面的代碼,函數将輸出 “Hello”,結果顯而易見,其中 await 将阻塞主線程,直到 promise 處理完成。

async

async 函數使我們能夠編寫基于 promise 的代碼,就像它是同步的一樣,但不會阻塞執行線程。

通過事件循環異步運作,async 函數将始終傳回一個值。

使用 async 簡單地将傳回一個 promise,如果 apromise 沒有傳回,會自動将它包裝在一個 promise 帶有它的值的 resolve 中。

await

await 運算符用于等待 promise ,它隻能在 async 塊内使用。關鍵字 await 使 JavaScript 等待直到 promise 傳回結果。

需要注意的是,它隻是讓 async 功能塊等待,而不是整個程式執行。不能在正常函數中使用 await 關鍵字。

猜猜下面代碼片段的輸出。

async function helloAsync() {
    const result = await new Promise((resolve) =>
        setTimeout(() => resolve("Hello"))
    );
    return result;
}
let asyncResult = helloAsync();
console.log("helloAsync傳回值:" + jsON.stringify(asyncResult));      

根據上面的代碼,可能會認為輸出 “Hello” ,對與錯要眼見為實,複制上面的代碼運作後,輸出為:asyncResult值:{},從輸出來看,變量 asyncResult 的值為{} 。

為什麼會這樣?

因為異步函數總是傳回一個承諾,而不是解決上面例子中的承諾,我們試圖從中提取價值。

如何解決?

由于 async 函數在上面的代碼片段中傳回了一個 promise 對象,那麼就可以使用 .then 方法擷取 async 函數的處理結果。

下面的代碼可以正常列印 async 函數的執行結果。

async function helloAsync() {
    const result = await new Promise((resolve) =>
        setTimeout(() => resolve("Hello"))
    );
    return result;
}


helloAsync().then((data) => {
    console.log("helloAsync傳回值:" + jsON.stringify(data));
});      
更好的方法

使用 async 和 await 主要是想避免使用 promise 鍊或 .then 表達式,是以可以使用 async 和 await 本身來解決 promise,而不是使用 .then,下面代碼為推薦使用方式:

async function helloAsync() {
    const result = await new Promise((resolve) =>
        setTimeout(() => resolve("Hello"))
    );
    return result;
}
async function testHelloAsync() {
    const output = await helloAsync();
    console.log("helloAsync傳回值:" + JSON.stringify(output));
}


testHelloAsync();      

總結

在實際開發項目中,是使用 Promises 還是 Async/Await 沒有好壞之分,取決于開發人員,我個人目前是偏向使用 Promises 的。

學習更多技能

請點選下方公衆号