JavaScript 異步調(diào)用
問(wèn)題
可修改下面的 aa() 函數(shù),目的是在一抄后用 console.log() 輸出 want-value
function aa() { setTimeout(function() { return "want-value"; }, 1000); }
但是,有額外要求:
aa() 函數(shù)可以隨意修改,但是不能有 console.log()
執(zhí)行 console.log() 語(yǔ)句里不能有 setTimeout 包裹
解答
也許這是個(gè)面試題,管它呢。問(wèn)題的主要目的是考察對(duì)異步調(diào)用執(zhí)行結(jié)果的處理,既然是異步調(diào)用,那么 不可能同步等待異步結(jié)果,結(jié)果一定是異步的
setTimeout() 經(jīng)常用來(lái)模擬異步操作。最早,異步是通過(guò)回調(diào)來(lái)通知(調(diào)用)處理程序處理結(jié)果的
function aa(callback) { setTimeout(function() { if (typeof callback === "function") { callback("want-value"); } }, 1000); } aa(function(v) { console.log(v); });
不過(guò)回調(diào)在用于稍大型一點(diǎn)的異步應(yīng)用時(shí),容易出現(xiàn)多層嵌套,所以之后提出了一些對(duì)其進(jìn)行“扁平”化,這一部分可以參考閑談異步調(diào)用“扁平”化。當(dāng)然 Promise 是非常流行的一種方法,并最終被 ES6 采納。用Promise 實(shí)現(xiàn)如下:
function aa() { return new Promise(resolve => { setTimeout(function() { resolve("want-value"); }, 1000); }); } aa().then(v => console.log(v));
就這個(gè)例子來(lái)說(shuō),它和前面回調(diào)的例子大同小異。不過(guò)它會(huì)引出目前更推薦的一種方法——async/await,從 ES2017 開(kāi)始支持:
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)用的時(shí)候,使用了 await ,異步等待,等待到異步的結(jié)果之后,再使用 console.log() 對(duì)其進(jìn)行處理。
這里需要注意的是 await 只能在 async 方法中使用,所以為了使用 await 必須定義一個(gè) async 的 main 方法,并在全局作用域中調(diào)用。由于 main 方法是異步的(申明為 async),所以如果 main() 調(diào)用之后還有其它語(yǔ)句,比如 console.log("hello") ,那么這一句話會(huì)先執(zhí)行。
async/await 語(yǔ)法讓異步調(diào)用寫(xiě)起來(lái)像寫(xiě)同步代碼,在編寫(xiě)代碼的時(shí)候,可以避免邏輯跳躍,寫(xiě)起來(lái)會(huì)更輕松。(參考: 從地獄到天堂,Node 回調(diào)向 async/await 轉(zhuǎn)變 )
當(dāng)然,定義 main() 再調(diào)用 main() 這部分可以用 IIFE 封裝一下,
(async () => { const v = await aa(); console.log(v); })();
總結(jié)
以上所述是小編給大家介紹的JavaScript 異步調(diào)用,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
原生JS forEach()和map()遍歷的區(qū)別、兼容寫(xiě)法及jQuery $.each、$.map遍歷操作
這篇文章主要介紹了原生JS forEach()和map()遍歷的區(qū)別、兼容寫(xiě)法及jQuery $.each、$.map遍歷操作,結(jié)合實(shí)例形式分析了JS使用forEach()和map()以及jQuery使用$.each、$.map進(jìn)行遍歷操作相關(guān)技巧與操作注意事項(xiàng),需要的朋友可以參考下2019-02-02利用Promise自定義一個(gè)GET請(qǐng)求的函數(shù)示例代碼
這篇文章主要給大家介紹了關(guān)于如何利用Promise自定義一個(gè)GET請(qǐng)求的函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Promise具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03javascript currentTarget對(duì)象介紹
javascript currentTarget對(duì)象介紹...2007-10-10Javascript實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊冒泡特效
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊冒泡特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12JS使用canvas中的measureText方法測(cè)量字體寬度示例
這篇文章主要介紹了JS使用canvas中的measureText方法測(cè)量字體寬度,結(jié)合實(shí)例形式分析了canvas的measureText方法相關(guān)使用技巧,需要的朋友可以參考下2019-02-02動(dòng)態(tài)的9*9乘法表效果的實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇?jiǎng)討B(tài)的9*9乘法表效果的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧2016-05-05javascript數(shù)組中的reduce方法和pop方法
這篇文章主要介紹了javascript數(shù)組中的reduce方法和pop方法,文章內(nèi)容介紹詳細(xì),具有一定的參考價(jià)值需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助2022-03-03JavaScript驗(yàn)證一個(gè)url的方法總結(jié)
最近遇到幾次需要校驗(yàn)URL的,使用這篇文章小編就為大家整理了一下幾個(gè)JavaScript校驗(yàn)URL的方法,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以了解一下2023-12-12