es7中的async、await使用方法示例詳解
async、await 是es7里面的新語(yǔ)法,它的作用就是 async 用于申明一個(gè) function 是異步的,而 await 用于等待一個(gè)異步方法執(zhí)行完成。它可以很好的替代promise 中的then。async 函數(shù)返回一個(gè) Promise 對(duì)象,可以使用then 方法添加回調(diào)函數(shù)。當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到await 就會(huì)先返回,等到異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句。
一、前言
回調(diào)是JavaScript在es5之前處理異步方法的常用方式,當(dāng)異步調(diào)用又調(diào)用了異步方法時(shí),前端的小伙伴們應(yīng)該都遇到過(guò)這種場(chǎng)景吧,回調(diào)方式的寫(xiě)法讓人看得頭皮發(fā)麻,代碼的可讀性非常差
ES2015中引入Promise, 目的就是為了解決著名的回調(diào)地獄,但是它自己引入了語(yǔ)法復(fù)雜性。示例如下:
function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } takeLongTime().then(v => { console.log("got", v); });
ES2017增加了異步函數(shù)async/await,提高了代碼可讀性,讓調(diào)用異步方法像同步一樣簡(jiǎn)單。示例如下:
function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } async function test() { const v = await takeLongTime(); console.log(v); } test();
async/await使代碼看起來(lái)像是同步的,但它在后臺(tái)是異步和非阻塞的??梢岳斫?await 后面的語(yǔ)句相當(dāng)于放到了 new Promise 中,下一行及之后的語(yǔ)句相當(dāng)于放在 Promise.then 中。 async 會(huì)將其后的函數(shù)(函數(shù)表達(dá)式或 Lambda)的返回值封裝成一個(gè) Promise 對(duì)象,而 await 會(huì)等待這個(gè) Promise 完成,并將其 resolve 的結(jié)果返回出來(lái)。
二、async 和 await 的基礎(chǔ)使用
async/awiat 的使用規(guī)則:
async 返回的是一個(gè) Promise 成功的對(duì)象,await 就是等待這個(gè) promise 的返回結(jié)果后,再繼續(xù)執(zhí)行
await 等待的是一個(gè) Promise 對(duì)象,后面必須跟一個(gè) Promise 對(duì)象,但是不必寫(xiě) then (),直接就可以得到返回值
但注意,await 所等待的 promise 對(duì)象,他的最終狀態(tài)一定是 resolve 的(當(dāng)然也可以不是 resolve ,只不過(guò)不會(huì)執(zhí)行后面的代碼罷了),否則不會(huì)執(zhí)行await 后面的代碼,也就是不會(huì)去執(zhí)行所謂的 then() ;
三、async \ await使用場(chǎng)景
//將請(qǐng)求改造成一個(gè)通用函數(shù) function request(options) { //..... return new Promise(....); //使用Promise執(zhí)行請(qǐng)求,并返回Promise對(duì)象 } //于是我們就可以來(lái)發(fā)送請(qǐng)求了 request("ajaxA") .then((data)=>{ //處理data return request("ajaxB") }) .then((data)=>{ //處理data return request("ajaxC") }) .then((data)=>{ //處理data return request("ajaxD") })
如果能像使用同步代碼那樣, 使用Promise就好了。于是, async \ await出現(xiàn)了
function request(options) { //..... return new Promise(....); //使用Promise執(zhí)行請(qǐng)求,并返回Promise對(duì)象 } //wait這個(gè)單詞是等待的意思 async function load(){ await request("ajaxA"); //那么這里就是在等待ajaxA請(qǐng)求的完成 await request("ajaxB"); await request("ajaxC"); await request("ajaxD"); }
await關(guān)鍵字使用的要求非常簡(jiǎn)單, 后面調(diào)用的函數(shù)要返回一個(gè)Promise對(duì)象。load()這個(gè)函數(shù)已經(jīng)不再是普通函數(shù), 它出現(xiàn)了await這樣"阻塞式"的操作 因此async關(guān)鍵字在這是不能省略的。與之前長(zhǎng)長(zhǎng)的then鏈和then方法里的回調(diào)函數(shù)相比,這樣的寫(xiě)法看起來(lái)像是同步寫(xiě)法并且更加清爽,更加符合編程習(xí)慣。
四、await返回打印測(cè)試
await后面的promise狀態(tài)不是resolve的輸出結(jié)果
async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1'); }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async1().then(res => console.log(res)) console.log('srcipt end') /* await后面的promise狀態(tài)不是resolve的輸出結(jié)果 "srcipt start" "async1 start" "promise1" "srcipt end" */
這里我們可以看到:在 async1 中 await 后面的 Promise 是沒(méi)有返回值的,也就是它的狀態(tài)始終是 pending 狀態(tài),所以在 await 之后的內(nèi)容是不會(huì)執(zhí)行的,包括 async1 后面的 .then。
await后面的promise狀態(tài)是resolve的輸出結(jié)果
async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1'); resolve() }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async1().then(res => console.log(res)) console.log('srcipt end') /*await后面的promise狀態(tài)是resolve的輸出結(jié)果 "srcipt start" "async1 start" "promise1" "srcipt end" "async1 success" "async1 end" */
五、總結(jié)
解決函數(shù)回調(diào)經(jīng)歷了幾個(gè)階段, Promise 對(duì)象, Generator 函數(shù)到async函數(shù)。async函數(shù)目前是解決函數(shù)回調(diào)的最佳方案。很多語(yǔ)言目前都實(shí)現(xiàn)了async,包括Python ,java spring,go等。
async 函數(shù)返回一個(gè) Promise 對(duì)象,當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到 await 就會(huì)先返回,等到觸發(fā)的異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句。
到此這篇關(guān)于es7中的async、await使用方法示例詳解的文章就介紹到這了,更多相關(guān)async、await使用示例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于ligerui子頁(yè)面關(guān)閉后,父頁(yè)面刷新,重新加載的方法
今天小編就為大家分享一篇關(guān)于ligerui子頁(yè)面關(guān)閉后,父頁(yè)面刷新,重新加載的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JavaScript使用pop方法移除數(shù)組最后一個(gè)元素用法實(shí)例
這篇文章主要介紹了JavaScript使用pop方法移除數(shù)組最后一個(gè)元素,實(shí)例分析了javascript中pop方法的使用技巧,需要的朋友可以參考下2015-04-04Bootstarp 基礎(chǔ)教程之表單部分實(shí)例代碼
這篇文章主要介紹了Bootstarp 基礎(chǔ)教程之表單部分實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-02-02把JS與CSS寫(xiě)在同一個(gè)文件里的書(shū)寫(xiě)方法
把JS與CSS寫(xiě)在同一個(gè)文件里的書(shū)寫(xiě)方法...2007-06-06js實(shí)現(xiàn)列表循環(huán)滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)列表循環(huán)滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07