這次帶給大家JS中的async/await,使用JS中的async/await的注意事項有哪些,下面就是實戰案例,一起來看一下。
JS中的非同步操作從最初的回呼函數演進到Promise,再到Generator,都是逐步的改進,而async函數的出現彷彿看到了非同步方案的終點,用同步的方式寫異步。
簡單解釋async函數就是Generator函數的語法糖。
Generator函數寫法
let promise = function (val){ return new Promise(function (resolve, reject){ setTimeout(()=>{ console.log(val); resolve(val); },1000); }); };let gen = function* (){ let p1 = yield promise('1'); let p2 = yield promise('2'); };let genF = gen();
async函數寫法
let promise = function (val){ return new Promise(function (resolve, reject){ setTimeout(()=>{ console.log(val); resolve(val); },1000); }); };let gen = async function (){ let p1 = await promise('1'); let p2 = await promise('2'); };
async函數是在Generator函數上的改進,語法上Generator函數的星號換成了async,yield換成了await。
而async也與Generator函數不同:
自帶內建執行器,Generator函數需要依賴執行器,而async可以和普通函數一樣,只需要一行
相對Generator函數,async和await語意比較清楚
適用性強,yield後只能是Thunk函數和Promise對象,而await後可以是Promise物件和原始型別的值(數值、字串、布林型等)
async作用
寄予async函數的期望是希望可以幫助我們解決非同步操作問題,所以需要搞清楚async函數的回傳值是什麼。
async function asyncAwait() { return 'async await'; }let a = asyncAwait();console.log(a);
結果輸出:
Promise {<resolved>: "async await"}
可以看出async函數回傳的是一個Promise對象,如果函數中return一個直接量,async函數會封裝成Promise物件返回,而如果沒有傳回值時,async函數會傳回undefined
Promise {<resolved>: undefined}
在沒有結合await時,async函數會立即執行,傳回一個Promise物件。
await等待
await是個運算子,等待的結果是Promise物件或其他值,例如:
function func1() { return 'async'; }async function func2() { return Promise.resolve('await'); }async function asyncAwait() { let f1 = await func1(); let f2 = await func2(); console.log(f1, f2); } asyncAwait()
結果輸出:
async await
await表達式的運算取決於等待的結果,如果它等到的不是一個Promise對象,那運算結果就是它等到的東西,
而如果它等到的是一個Promise對象,它會阻塞後面的程式碼,等著Promise物件resolve,然後得到resolve的值,作為表達式的運算結果。
async函數呼叫會封裝在Promise中,這也是await需要在async函數中使用的原因。
async/await鍊式處理
對於多個非同步操作中,Promise的then可以解決多層回呼問題。
function ajax(t) { return new Promise(resolve => { setTimeout(() => resolve(t + 200), t); }); }function step1(t) { console.log(`step1 in ${t}ms`); return ajax(t); }function step2(t) { console.log(`step2 in ${t}ms`); return ajax(t); }function step3(t) { console.log(`step3 in ${t}ms`); return ajax(t); }function submit(){ console.time('submit'); step1(200) .then(time2 => step2(time2)) .then(time3 => step3(time3)) .then(result => { console.log(`result is ${result}ms`); console.timeEnd("submit"); }); }
submit();
async函數實作:
function ajax(t) { return new Promise(resolve => { setTimeout(() => resolve(t + 200), t); }); }function step1(t) { console.log(`step1 in ${t}ms`); return ajax(t); }function step2(t) { console.log(`step2 in ${t}ms`); return ajax(t); }function step3(t) { console.log(`step3 in ${t}ms`); return ajax(t); }async function submit(){ console.time('submit'); const t1 = 200; const t2 = await step1(t1); const t3 = await step2(t2); const result = await step3(t3); console.log(`result is ${result}`); console.timeEnd('submit'); } submit();
結果輸出:
step1 in 200ms step2 in 400ms step3 in 600ms result is 800submit: 1209.85107421875ms
而如果需求變更,每一步的參數都是先前步驟的結果後,async函數可以寫成:
function ajax(t) { return new Promise(resolve => { setTimeout(() => resolve(t + 200), t); }); }function step1(t1) { console.log(`step1 in ${t1}ms`); return ajax(t1); }function step2(t1, t2) { console.log(`step2 in ${t1}ms,${t2}ms`); return ajax(t1 + t2); }function step3(t1, t2, t3) { console.log(`step3 in ${t1}ms,${t2}ms,${t3}ms`); return ajax(t1 + t2 + t3); }async function submit(){ console.time('submit'); const t1 = 200; const t2 = await step1(t1); const t3 = await step2(t1, t2); const result = await step3(t1, t2, t3); console.log(`result is ${result}`); console.timeEnd('submit'); } submit();
結果輸出:
step1 in 200ms step2 in 200ms,400ms step3 in 200ms,400ms,800ms result is 1600submit: 2210.47998046875ms
async/await注意點
async用來申明裡麵包裹的內容可以進行同步的方式執行,await則是進行執行順序控制,每次執行一個await,阻塞程式碼執行等待await回傳值,然後再執行之後的await。
await後面呼叫的函數需要傳回一個promise。
await只能用在async函數之中,用在普通函數中會報錯。
await指令後面的Promise對象,執行結果可能是rejected,所以最好把await指令放在try...catch程式碼區塊中。
async/await try/catch寫法
async function asyncAwait() { try { await promise(); } catch (err) { console.log(err); } }// 另一种写法async function asyncAwait() { await promise().catch(function (err){ console.log(err); }); }
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是JS中的async/await的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版
中文版,非常好用

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境