js異步之a(chǎn)sync和await實現(xiàn)同步寫法
首先我們假設(shè)有一方法 readFile 可以讀取文件內(nèi)容, 但是它是異步的。
var gen = function* (){ ? ? var a = yield readFile('./a.txt'); ? ? console.log(a.toString()); ? ? var b = yield readFile('./b.txt'); ? ? console.log(b.toString()); };
首先我們看下上面的代碼,如果我們將function 后面的 * 改成 async,將yield 改成 await,也就是下面的代碼
var gen = function async (){ ? ? var a = await readFile('./a.txt'); ? ? console.log(a.toString()); ? ? var b = await readFile('./b.txt'); ? ? console.log(b.toString()); };
是不是就是我們想要的同步寫異步操作了,第一種寫法就是 es6 中新支持的特性,Generator 函數(shù),那什么是 Generator 函數(shù)呢,簡單來說Generator 函數(shù)有多種理解角度。語法上,首先可以把它理解成,Generator 函數(shù)是一個狀態(tài)機,封裝了多個內(nèi)部狀態(tài)。執(zhí)行 Generator 函數(shù)會返回一個遍歷器對象,也就是說,Generator 函數(shù)除了狀態(tài)機,還是一個遍歷器對象生成函數(shù)。返回的遍歷器對象,可以依次遍歷 Generator 函數(shù)內(nèi)部的每一個狀態(tài)。上面的官方解釋看不懂沒關(guān)系。我們下面用例子演示下。
function* func(){? ? ? console.log("one");? ? ? yield '1';? ? ? console.log("two");? ? ? yield '2';? ? ? console.log("three");? ? ? return '3';? } var f = func(); f.next(); // one // {value: "1", done: false}? f.next(); // two // {value: "2", done: false}? f.next(); // three // {value: "3", done: true}? f.next(); // {value: undefined, done: true}
上面的代碼我們第一次調(diào)用 f.next() 時,函數(shù) func 開始執(zhí)行,并在執(zhí)行到第一個 yield 時停住,并返回 yield 后面表達式的值,格式就是 {value: "1", done: false} 這種格式,value就是 yield 表達式的值
done 表示func函數(shù)是否執(zhí)行完畢,此時如果我們?nèi)绻又{(diào)用 f.next(),類推將返回第二 yield 后面表達式的值,也就是 {value: "2", done: false}。我們可以繼續(xù)調(diào)用 f.next() 直至 done 變成 true, 它表示func函數(shù)執(zhí)行完了。
function* func(){ ? ? var a = yield '1'; ? ? console.log(a); ? ? var b = yield '2'; ? ? console.log(b); } var f = func(); f.next();? f.next('1');?
f.next('2');我們繼續(xù)改造 func 函數(shù)為上面這種,在 next 分別傳入 1 和 2,我們會發(fā)現(xiàn) console.log(a) 打印 1 ,console.log(b) 打印 2,也就是我們可以傳值到 Generator 函數(shù)中。
現(xiàn)在我們回到下面這段代碼上面來,然后重新設(shè)計下,并實現(xiàn) readFile 函數(shù)。
var gen = function* (){ ? ? var a = yield readFile('./a.txt'); ? ? console.log(a.toString()); ? ? var b = yield readFile('./b.txt'); ? ? console.log(b.toString()); }; var readFile = function (fileName){ ? ? return new Promise((resolve)=>{ ? ? ? ? fs.readFile(fileName, (err, data)=>{ ? ? ? ? ? ? resolve(data); ? ? ? ? }) ? ? }); }; function run(fn) { ? ? var gen = fn(); ? ? function next(data) { ? ? ? ? var result = gen.next(data); ? ? ? ? if (result.done) return; ? ? ? ? result.value.then((data)=>{ ? ? ? ? ? ? next(data); ? ? ? ? }) ? ? } ? ? next(); } run(gen);
看上面的代碼我們用 promise 實現(xiàn) readFile 函數(shù),此時我們 yield 的返回值就是一個 promise 對象了,我們就可以使用, result.value.then((data)=>{next(data);})
將 yield 返回的 value 值重新傳回 Generator 函數(shù),這樣我們的 console.log(a.toString()); 就可以獲取到 a.txt 文件中的內(nèi)容了, if (result.done) return; 可以用了判斷 Generator 函數(shù) 是否已執(zhí)行完畢,用來結(jié)束循環(huán)調(diào)用。所以如果我們單獨去看 gen 函數(shù),是不是就是將異步操作寫成同步語法了,如果我們將function 后面的 * 改成 async,將yield 改成 await也就是我們常用語法了。
到此這篇關(guān)于js異步之a(chǎn)sync和await實現(xiàn)同步寫法的文章就介紹到這了,更多相關(guān)js async和await同步內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript返回網(wǎng)頁中錨點數(shù)目的方法
這篇文章主要介紹了JavaScript返回網(wǎng)頁中錨點數(shù)目的方法,涉及javascript使用document.anchors獲取錨點數(shù)目的技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04腳本吧 - 幻宇工作室用到j(luò)s,超強推薦base.js
腳本吧 - 幻宇工作室用到j(luò)s,超強推薦base.js...2006-12-12Web 開發(fā)中Ajax的Session 超時處理方法
下面小編就為大家?guī)硪黄猈eb 開發(fā)中Ajax的Session 超時處理方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01JavaScript實現(xiàn)數(shù)組分塊的四種方法
在前端開發(fā)的日常工作中,處理數(shù)組是家常便飯,尤其是在面對海量數(shù)據(jù)渲染、性能優(yōu)化等場景時,將大數(shù)組按照指定大小進行分塊處理,成了一個非常實用的技能,今天咱們就來聊聊,如何用JavaScript實現(xiàn)數(shù)組分塊,需要的朋友可以參考下2025-04-04IE下通過a實現(xiàn)location.href 獲取referer的值
IE下采用window.location.href方式跳轉(zhuǎn)的話,referer值為空在標簽a里面的跳轉(zhuǎn)的話referer就不會空,下面是具體的實現(xiàn)代碼2014-09-09關(guān)于javaScript注冊click事件傳遞參數(shù)的不成功問題
在javaScript中給一個html元素注冊click事件處理函數(shù)時,比如給該處理函數(shù)傳3個參數(shù)??墒遣还苁鞘褂孟旅婺欠N方式都不能給事件處理函數(shù)傳遞參數(shù)2014-07-07