异步编程的 async/await
async/await 和 Generators + co 的寫法非常的相似,只是把用于聲明 Generator 函數(shù)的 * 關(guān)鍵字替換成了 async 并寫在了 function 關(guān)鍵字的前面,把 yield 關(guān)鍵字替換成了 await;另外,async 函數(shù)是基于 Promise 的,await 關(guān)鍵字后面等待的異步操作必須是一個 Promise 實例,當然也可以是原始類型的值,只不過這時的執(zhí)行效果等同于同步,與 Generator 不同的是,await 關(guān)鍵字前可以使用變量去接收這個正在等待的 Promise 實例執(zhí)行后的結(jié)果。
async 函數(shù)的基本用法
async 函數(shù)返回一個 Promise 實例,可以使用 then 方法添加回調(diào)函數(shù)。當函數(shù)執(zhí)行的時候,只要遇到 await 就會等待,直到 await 后面的同步或異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語句。
ES6的聲明
// 1- 函數(shù)聲明function * fn() {}// 2- 函數(shù)表達式const * fn = function() {};ES7的聲明
// 1- 函數(shù)聲明 async function fn() {}// 2- 函數(shù)表達式 const fn = async function() {};// 3- 箭頭函數(shù) const fn = async () => {};// 4- 作為對象的方法 let obj = {async fn() {} };// 5- 作為 class 的方法 class Person(name) {constructor () {this.name = name;}async getName() {const name = await this.name;return name;} }使用 NodeJS 的 fs 模塊連續(xù)異步讀文件,第一個文件名為 a.txt,讀到的內(nèi)容為 b.txt,作為要讀的第二個文件的文件名,繼續(xù)讀 b.txt 后將讀到的內(nèi)容 “Hello world” 打印出來。
我們來使用 async/await 的方式來實現(xiàn)一下:
與 Generator 函數(shù)一樣,寫法像同步,執(zhí)行是異步,不同的是我們即沒有手動調(diào)用 next 方法,也沒有借助 co 庫,其實是 async 函數(shù)內(nèi)部集成了類似于 co 的執(zhí)行器,幫我們在異步完成后自動向下執(zhí)行代碼,所以說 async/await 是 Generators + co 的語法糖。
await 異步并發(fā)
在 async 函數(shù)中,如果有多個 await 互不依賴,這種情況下如果執(zhí)行一個,等待一個完成,再執(zhí)行一個,再等待完成,這樣是很浪費性能的,所以我們要把這些異步操作同時觸發(fā)。
假設(shè)我們異步讀取兩個文件,且這兩個文件不相關(guān),我可以使用下面的方式來實現(xiàn):
// 前置 let fs = require("fs"); let util = require("util"); let readFile = util.promisify(fs.readFile);// 方法1- 需要改進的 async 函數(shù) async function fn() {let aData = await readFile("a.txt", "utf8");let bData = await readFile("b.txt", "utf8");return [aData, bData]; }fn();// 方法2- 在 async 函數(shù)外部觸發(fā)異步 let aDataPromise = readFile("a.txt", "utf8"); let bDataPromise = readFile("b.txt", "utf8");async function fn() {let aData = await aDataPromise;let bData = await bDataPromise;return [aData, bData]; }fn();// 方法3- 使用 Promise.all async function fn() {let dataArr = await Promise.all(readFile("a.txt", "utf8"),readFile("a.txt", "utf8"));return dataArr; }fn();異步并發(fā)實例
// 創(chuàng)建 Promise 實例 let p1 = Promise.resolve("p1 success"); let p2 = Promise.resolve("p2 success"); let p3 = Promise.resolve("p3 success");// 1-錯誤的處理方式 async 函數(shù) async function fn(promises) {promise.forEach(function (promise) {await promise;}); }fn([p1, p2, p3]); // 執(zhí)行時報錯// 2-正確的打開方式 修改方式 async function fn(promises) {for(let i = 0; i < promises.length; i++) {await promises[i];} }fn([p1, p2, p3]); // 正常執(zhí)行總結(jié)
以上是生活随笔為你收集整理的异步编程的 async/await的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Iterator 遍历器的简单使用
- 下一篇: 王者荣耀7小时禁赛时间规则