可修改下面的 aa()
函數(shù),目的是在一秒后用 console.log()
輸出 want-value
function aa() { setTimeout(function() { return "want-value"; }, 1000); }
但是,有額外要求:
aa()
函數(shù)可以隨意修改,但是不能有 console.log()
執(zhí)行 console.log()
語句里不能有 setTimeout
包裹
也許這是個面試題,管它呢。問題的主要目的是考察對異步調(diào)用執(zhí)行結(jié)果的處理,既然是異步調(diào)用,那么不可能同步等待異步結(jié)果,結(jié)果一定是異步的
setTimeout()
經(jīng)常用來模擬異步操作。最早,異步是通過回調(diào)來通知(調(diào)用)處理程序處理結(jié)果的
function aa(callback) { setTimeout(function() { if (typeof callback === "function") { callback("want-value"); } }, 1000); } aa(function(v) { console.log(v); });
不過回調(diào)在用于稍大型一點的異步應(yīng)用時,容易出現(xiàn)多層嵌套,所以之后提出了一些對其進行“扁平”化,這一部分可以參考閑談異步調(diào)用“扁平”化。當然 Promise 是非常流行的一種方法,并最終被 ES6 采納。用 Promise 實現(xiàn)如下:
function aa() { return new Promise(resolve => { setTimeout(function() { resolve("want-value"); }, 1000); }); } aa().then(v => console.log(v));
就這個例子來說,它和前面回調(diào)的例子大同小異。不過它會引出目前更推薦的一種方法——async/await,從 ES2017 開始支持:
function aa() { return new Promise(resolve => { setTimeout(function() { resolve("want-value"); }, 1000); }); } async function main() { const v = await aa(); console.log(v); } main();
aa()
的定義與 Promise 方法中的定義是一樣的,但是在調(diào)用的時候,使用了 await
,異步等待,等待到異步的結(jié)果之后,再使用 console.log()
對其進行處理。
這里需要注意的是 await
只能在 async
方法中使用,所以為了使用 await
必須定義一個 async
的 main 方法,并在全局作用域中調(diào)用。由于 main 方法是異步的(申明為 async),所以如果 main()
調(diào)用之后還有其它語句,比如 console.log("hello")
,那么這一句話會先執(zhí)行。
async/await 語法讓異步調(diào)用寫起來像寫同步代碼,在編寫代碼的時候,可以避免邏輯跳躍,寫起來會更輕松。(參考:從地獄到天堂,Node 回調(diào)向 async/await 轉(zhuǎn)變)
當然,定義 main()
再調(diào)用 main()
這部分可以用 IIFE 封裝一下,
(async () => { const v = await aa(); console.log(v); })();
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com