JS Generator 函數(shù)的含義與用法實(shí)例總結(jié)
本文實(shí)例講述了JS Generator 函數(shù)的含義與用法。分享給大家供大家參考,具體如下:
讀阮一峰老師《Generator 函數(shù)的含義與用法》總結(jié)
老師的文章通俗易懂,但是我個(gè)人理解上面有一些差,所以看了幾遍之后才有呢么一點(diǎn)點(diǎn)體會(huì)
把它記錄下來(lái)。
還是那句話,所有事物的出現(xiàn)都是為了解決對(duì)應(yīng)的問題。
那么Generator出現(xiàn)是為了解決什么問題的呢?
在異步編程的場(chǎng)景下,如果有多個(gè)異步任務(wù),如何處理他們的先后執(zhí)行順序?
舉一個(gè)常見的例子,jquery的ajax請(qǐng)求,每一個(gè)success都是一個(gè)異步任務(wù)。
那么問題來(lái)了,如果我要保證頁(yè)面渲染要在5個(gè)網(wǎng)絡(luò)請(qǐng)求都回來(lái)之后再去渲染頁(yè)面。
我們的代碼就會(huì)變成:
$.ajax({...success:function(data){
$.ajax({...success:function(data){
$.ajax({...success:function(data){
$.ajax({...success:function(data){
$.ajax({...success:function(data){
//do something
}})
}})
}})
}})
}})
這就是”回調(diào)函數(shù)噩夢(mèng)”(callback hell)
為了解決這個(gè)問題,后來(lái)出現(xiàn)了Deferred和promise
兩者區(qū)別不大,通過(guò)一種包裝寫法來(lái)減少回調(diào)函數(shù)
上面的ajax就可以寫成:
ajax1 = $.ajax({...success:function(data){});
ajax2 = $.ajax({...success:function(data){});
ajax3 = $.ajax({...success:function(data){});
ajax4 = $.ajax({...success:function(data){});
ajax5 = $.ajax({...success:function(data){});
$.when(ajax1,ajax2,ajax3,ajax4,ajax5).done(function(
//do something
)).then(function(){
//do something2
})
1.8版本以上的jquery ajax模塊默認(rèn)返回Deferred對(duì)象
Deferred和promise將回調(diào)函數(shù)做拆分,將異步任務(wù)的處理和執(zhí)行分成兩部分完成
他們最大的問題就是代碼冗余,包裝之后的代碼都需要通過(guò)then,done來(lái)執(zhí)行后面的內(nèi)容,也導(dǎo)致層次感不清晰
那有沒有一種比較無(wú)感,簡(jiǎn)單的寫法呢?
那就是協(xié)程,
我之前也是在這個(gè)地方困惑了很久,
前面說(shuō)的大多日常用到過(guò),也清楚一些原理,
關(guān)于協(xié)程用到的就少了,我們來(lái)分析下吧。
直接看一下協(xié)程的例子:
function asnycJob() {
// ...其他代碼
var f = yield readFile(fileA);
// ...其他代碼
}
阮一峰老師的原話:
上面代碼的函數(shù) asyncJob 是一個(gè)協(xié)程,它的奧妙就在其中的 yield 命令。它表示執(zhí)行到此處,執(zhí)行權(quán)將交給其他協(xié)程。也就是說(shuō),yield命令是異步兩個(gè)階段的分界線。 協(xié)程遇到 yield 命令就暫停,等到執(zhí)行權(quán)返回,再?gòu)臅和5牡胤嚼^續(xù)往后執(zhí)行。它的最大優(yōu)點(diǎn),就是代碼的寫法非常像同步操作,如果去除yield命令,簡(jiǎn)直一模一樣。
之前沒理解的原因就是沒好好讀這兩句話,今認(rèn)真看了一下,茅塞頓開。重要的有這么幾點(diǎn)
首先asnycJob這個(gè)方法就是一個(gè)協(xié)程
yield相當(dāng)于return,會(huì)返回當(dāng)前程序的執(zhí)行狀態(tài)
當(dāng)執(zhí)行到y(tǒng)ield,程序掛起等待返回后繼續(xù)執(zhí)行。
掛起這段時(shí)間去執(zhí)行其他協(xié)程函數(shù)
Generator函數(shù)是ES6對(duì)協(xié)程函數(shù)的實(shí)現(xiàn),
Generator函數(shù)的特點(diǎn)就是可以暫停代碼執(zhí)行。
跟協(xié)程函數(shù)一樣,遇到y(tǒng)ield關(guān)鍵字就暫停代碼執(zhí)行,
跟普通函數(shù)的區(qū)別在于Generator函數(shù)不會(huì)反悔結(jié)果,而是返回指針對(duì)象,
通過(guò)指針的next方法移動(dòng)指針指向下一個(gè)yield關(guān)鍵字位置。
也就是說(shuō)Generator函數(shù)的分階段執(zhí)行是由next方法控制的。
使用了Generator函數(shù)之后會(huì)對(duì)我們的代碼有多大的改變呢?
fangction* gen(){
var url = 'user/get/info';
var data = yield $.get({url:url});
console.log(data.userName);
}
你不需要擔(dān)心遠(yuǎn)程接口的返回時(shí)機(jī),完全按照同步的方式寫代碼就行。
但是也有缺點(diǎn),Generator函數(shù)把一步操作做的很簡(jiǎn)潔,但對(duì)流程的管理卻不方便,
上面的例子如何執(zhí)行?
var g = gen(); g.next(); g.next();
next 方法的作用是分階段執(zhí)行 Generator 函數(shù)。每次調(diào)用 next 方法,會(huì)返回一個(gè)對(duì)象,
表示當(dāng)前階段的信息( value 屬性和 done 屬性)。value 屬性是 yield 語(yǔ)句后面表達(dá)式的值,表示當(dāng)前階段的值;
done 屬性是一個(gè)布爾值,表示 Generator 函數(shù)是否執(zhí)行完畢,即是否還有下一個(gè)階段。
你需要執(zhí)行兩次.next方法,來(lái)將你的Generator函數(shù)執(zhí)行完畢。
關(guān)于如何自動(dòng)化異步任務(wù)的流程管理,就需要co,thunk,async的幫助了
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專題:《JavaScript常用函數(shù)技巧匯總》、《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- JavaScript前端迭代器Iterator與生成器Generator講解
- JavaScript?Generator異步過(guò)度的實(shí)現(xiàn)詳解
- Javascript生成器(Generator)的介紹與使用
- JS為什么說(shuō)async/await是generator的語(yǔ)法糖詳解
- js中Generator函數(shù)的深入講解
- JavaScript 中使用 Generator的方法
- js使用generator函數(shù)同步執(zhí)行ajax任務(wù)
- 深入理解js generator數(shù)據(jù)類型
- JavaScript Generator函數(shù)使用分析
相關(guān)文章
JavaScript?函數(shù)表達(dá)式與函數(shù)聲明的用法及區(qū)別
這篇文章主要介紹了JavaScript?函數(shù)表達(dá)式與函數(shù)聲明詳析,函數(shù)表達(dá)式和函數(shù)聲明是JavaScript中創(chuàng)建函數(shù)的兩種方法,下面文章具體的相關(guān)內(nèi)容介紹,需要的小伙伴可以參考一下2022-06-06
基于JavaScript實(shí)現(xiàn)Tab選項(xiàng)卡切換效果
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)Tabs選項(xiàng)卡切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
詳解設(shè)置Webstorm 利用babel將ES6自動(dòng)轉(zhuǎn)碼成ES5
這篇文章主要介紹了詳解設(shè)置Webstorm 利用babel將ES6自動(dòng)轉(zhuǎn)碼成ES5,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
從jQuery.camelCase()學(xué)習(xí)string.replace() 函數(shù)學(xué)習(xí)
camelCase函數(shù)的功能就是將形如background-color轉(zhuǎn)化為駝峰表示法:backgroundColor。2011-09-09
JavaScript中隨機(jī)數(shù)方法?Math.random()
這篇文章主要介紹了JavaScript中隨機(jī)數(shù)方法?Math.random(),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06
javascript不同頁(yè)面?zhèn)髦档母倪M(jìn)版
改進(jìn)點(diǎn):支持同頁(yè)面有多個(gè)文本框,可自動(dòng)向不同的文本框傳值。先看演示吧2008-09-09
ES6中async函數(shù)與await表達(dá)式的基本用法舉例
async和await是我們進(jìn)行Promise時(shí)的一個(gè)語(yǔ)法糖,async/await為了讓我們書寫代碼時(shí)更加流暢,增強(qiáng)了代碼的可讀性,下面這篇文章主要給大家介紹了關(guān)于ES6中async函數(shù)與await表達(dá)式的基本用法,需要的朋友可以參考下2022-07-07

