這次帶給大家怎樣優化node Async/Await非同步程式,優化node Async/Await非同步程式設計的注意事項有哪些,下面就是實戰案例,一起來看一下。
一、非同步程式設計的終極解決方案
#前幾天寫過關於javascript 非同步操作的文章《 Javascript Promise 詳解》. 最近在學習Puppeteer 的時候又發現另一種非同步程式設計解決方案:Async/Await.
非同步操作是JavaScript 程式設計的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個問題。從最早的回呼函數,到 Promise 物件,再到 Generator 函數,每次都有所改進,但又讓人覺得不徹底。它們都有額外的複雜性,都需要理解抽象的底層運作機制。
在 Async 函數出來之後,有人認為它是非同步程式設計的最終解決方案。因為有了 Async/Await 之後,你根本就不用在乎是它是不是非同步程式設計。
二、基本用法
async 函數傳回一個 Promise 對象,可以使用 then 方法新增回呼函數。當函數執行的時候,一旦遇到 await 就會先回,等到觸發的非同步操作完成,再接著執行函數體內後面的語句。
下面是一個栗子:
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, time); }) }; var start = async function () { // 在这里使用起来就像同步代码那样直观 console.log('start'); await sleep(3000); console.log('end'); }; start();
執行上面的程式碼,你會發現,控制台先輸出start,稍等3秒後,輸出了end。
三、注意事項
1、await 指令只能用在async 函數之中,如果用在普通函數,就會報錯。
async function dbFuc(db) { let docs = [{}, {}, {}]; // 报错 docs.forEach(function (doc) { await db.post(doc); }); }
2、await 表示在這裡等待promise回傳結果了,再繼續執行。
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { // 返回 ‘ok' resolve('ok'); }, time); }) }; var start = async function () { let result = await sleep(3000); console.log(result); // 收到 ‘ok' };
3、await 後面跟著的應該是一個promise物件。
如果是同步執行的程式碼沒有必要使用 await 修飾了。
4、await 只能使用在原生語法中,例如在 forEeach 結構中使用 await 是無法正常運作的,必須使用 for 迴圈的原生語法。
async function dbFuc(db) { let docs = [{}, {}, {}]; // 可能得到错误结果 docs.forEach(async function (doc) { await db.post(doc); }); }
如果確實希望多個請求並發執行,可以使用 Promise.all 方法。
async function dbFuc(db) { let docs = [{}, {}, {}]; let promises = docs.map((doc) => db.post(doc)); let results = await Promise.all(promises); console.log(results); }
四、錯誤捕獲
#既然.then(..)不用寫了,那麼.catch(..)也不用寫,可以直接用標準的try catch語法捕捉錯誤。
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { // 模拟出错了,返回 ‘error' reject('error'); }, time); }) }; var start = async function () { try { console.log('start'); await sleep(3000); // 这里得到了一个返回错误 // 所以以下代码不会被执行了 console.log('end'); } catch (err) { console.log(err); // 这里捕捉到错误 `error` } };
我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
React怎樣在react-router路由實作登陸驗證控制
以上是怎樣優化node Async/Await非同步編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!