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ù)呢,簡單來說Generator 函數(shù)有多種理解角度。語法上,首先可以把它理解成,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ù),是不是就是將異步操作寫成同步語法了,如果我們將function 后面的 * 改成 async,將yield 改成 await也就是我們常用語法了。
到此這篇關(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面向?qū)ο蟪绦蛟O(shè)計(jì)中對(duì)象的定義和繼承詳解
這篇文章主要介紹了JavaScript面向?qū)ο蟪绦蛟O(shè)計(jì)中對(duì)象的定義和繼承,結(jié)合實(shí)例形式詳細(xì)分析了javascript面向?qū)ο蟪绦蛟O(shè)計(jì)中對(duì)象定義、繼承、屬性、方法、深拷貝等相關(guān)概念與操作技巧,需要的朋友可以參考下2019-07-07解決JS浮點(diǎn)數(shù)運(yùn)算出現(xiàn)Bug的方法
解決JS浮點(diǎn)數(shù)運(yùn)算出現(xiàn)Bug的方法,需要的朋友可以參考一下2013-03-03easyui tree帶checkbox實(shí)現(xiàn)單選的簡單實(shí)例
下面小編就為大家?guī)硪黄猠asyui tree帶checkbox實(shí)現(xiàn)單選的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11director.js實(shí)現(xiàn)前端路由使用實(shí)例
這篇文章主要介紹了director.js實(shí)現(xiàn)前端路由使用實(shí)例,director.js是最純粹的路由注冊(cè)/解析器,它在不刷新頁面的情況下,利用“#”符號(hào)組織不同的URL路徑,需要的朋友可以參考下2015-02-02JS+JSP通過img標(biāo)簽調(diào)用實(shí)現(xiàn)靜態(tài)頁面訪問次數(shù)統(tǒng)計(jì)的方法
這篇文章主要介紹了JS+JSP通過img標(biāo)簽調(diào)用實(shí)現(xiàn)靜態(tài)頁面訪問次數(shù)統(tǒng)計(jì)的方法,基于JavaScript動(dòng)態(tài)調(diào)用jsp頁面通過對(duì)TXT文本文件的讀寫實(shí)現(xiàn)統(tǒng)計(jì)訪問次數(shù)的功能,需要的朋友可以參考下2015-12-12基于HTML5上使用iScroll實(shí)現(xiàn)下拉刷新,上拉加載更多
本文主要介紹在HTML5中使用iScroll實(shí)現(xiàn)下拉刷新,上拉加載更多數(shù)據(jù)的方法,主要就是寫了兩個(gè)自定義函數(shù)pullDownAction和pullUpAction,分別在下拉和上拉的事件中調(diào)用他們。2016-05-05