js異步之a(chǎn)sync和await實(shí)現(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ù)呢,簡(jiǎn)單來說Generator 函數(shù)有多種理解角度。語(yǔ)法上,首先可以把它理解成,Generator 函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。執(zhí)行 Generator 函數(shù)會(huì)返回一個(gè)遍歷器對(duì)象,也就是說,Generator 函數(shù)除了狀態(tài)機(jī),還是一個(gè)遍歷器對(duì)象生成函數(shù)。返回的遍歷器對(duì)象,可以依次遍歷 Generator 函數(shù)內(nèi)部的每一個(gè)狀態(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í),函數(shù) func 開始執(zhí)行,并在執(zhí)行到第一個(gè) yield 時(shí)停住,并返回 yield 后面表達(dá)式的值,格式就是 {value: "1", done: false} 這種格式,value就是 yield 表達(dá)式的值
done 表示func函數(shù)是否執(zhí)行完畢,此時(shí)如果我們?nèi)绻又{(diào)用 f.next(),類推將返回第二 yield 后面表達(dá)式的值,也就是 {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,我們會(huì)發(fā)現(xiàn) console.log(a) 打印 1 ,console.log(b) 打印 2,也就是我們可以傳值到 Generator 函數(shù)中。
現(xiàn)在我們回到下面這段代碼上面來,然后重新設(shè)計(jì)下,并實(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 實(shí)現(xiàn) readFile 函數(shù),此時(shí)我們 yield 的返回值就是一個(gè) promise 對(duì)象了,我們就可以使用, 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)用。所以如果我們單獨(dú)去看 gen 函數(shù),是不是就是將異步操作寫成同步語(yǔ)法了,如果我們將function 后面的 * 改成 async,將yield 改成 await也就是我們常用語(yǔ)法了。
到此這篇關(guān)于js異步之a(chǎn)sync和await實(shí)現(xiàn)同步寫法的文章就介紹到這了,更多相關(guān)js async和await同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript返回網(wǎng)頁(yè)中錨點(diǎn)數(shù)目的方法
這篇文章主要介紹了JavaScript返回網(wǎng)頁(yè)中錨點(diǎn)數(shù)目的方法,涉及javascript使用document.anchors獲取錨點(diǎn)數(shù)目的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04腳本吧 - 幻宇工作室用到j(luò)s,超強(qiáng)推薦base.js
腳本吧 - 幻宇工作室用到j(luò)s,超強(qiáng)推薦base.js...2006-12-12Web 開發(fā)中Ajax的Session 超時(shí)處理方法
下面小編就為大家?guī)硪黄猈eb 開發(fā)中Ajax的Session 超時(shí)處理方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01JavaScript實(shí)現(xiàn)數(shù)組分塊的四種方法
在前端開發(fā)的日常工作中,處理數(shù)組是家常便飯,尤其是在面對(duì)海量數(shù)據(jù)渲染、性能優(yōu)化等場(chǎng)景時(shí),將大數(shù)組按照指定大小進(jìn)行分塊處理,成了一個(gè)非常實(shí)用的技能,今天咱們就來聊聊,如何用JavaScript實(shí)現(xiàn)數(shù)組分塊,需要的朋友可以參考下2025-04-04JavaScript對(duì)象屬性操作實(shí)例解析
這篇文章主要介紹了JavaScript對(duì)象屬性操作實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02Echarts圖表分析巴西隊(duì)歷年戰(zhàn)績(jī)實(shí)例詳解
這篇文章主要為大家介紹了Echarts圖表分析巴西隊(duì)歷年戰(zhàn)績(jī)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12IE下通過a實(shí)現(xiàn)location.href 獲取referer的值
IE下采用window.location.href方式跳轉(zhuǎn)的話,referer值為空在標(biāo)簽a里面的跳轉(zhuǎn)的話referer就不會(huì)空,下面是具體的實(shí)現(xiàn)代碼2014-09-09關(guān)于javaScript注冊(cè)click事件傳遞參數(shù)的不成功問題
在javaScript中給一個(gè)html元素注冊(cè)click事件處理函數(shù)時(shí),比如給該處理函數(shù)傳3個(gè)參數(shù)??墒遣还苁鞘褂孟旅婺欠N方式都不能給事件處理函數(shù)傳遞參數(shù)2014-07-07