JS Generator 函數的含義與用法實例總結
本文實例講述了JS Generator 函數的含義與用法。分享給大家供大家參考,具體如下:
讀阮一峰老師《Generator 函數的含義與用法》總結
老師的文章通俗易懂,但是我個人理解上面有一些差,所以看了幾遍之后才有呢么一點點體會
把它記錄下來。
還是那句話,所有事物的出現都是為了解決對應的問題。
那么Generator出現是為了解決什么問題的呢?
在異步編程的場景下,如果有多個異步任務,如何處理他們的先后執行順序?
舉一個常見的例子,jquery的ajax請求,每一個success都是一個異步任務。
那么問題來了,如果我要保證頁面渲染要在5個網絡請求都回來之后再去渲染頁面。
我們的代碼就會變成:
$.ajax({...success:function(data){ $.ajax({...success:function(data){ $.ajax({...success:function(data){ $.ajax({...success:function(data){$.ajax({...success:function(data){ //do something}}) }}) }}) }})}})
這就是”回調函數噩夢”(callback hell)
為了解決這個問題,后來出現了Deferred和promise
兩者區別不大,通過一種包裝寫法來減少回調函數
上面的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模塊默認返回Deferred對象
Deferred和promise將回調函數做拆分,將異步任務的處理和執行分成兩部分完成
他們最大的問題就是代碼冗余,包裝之后的代碼都需要通過then,done來執行后面的內容,也導致層次感不清晰
那有沒有一種比較無感,簡單的寫法呢?
那就是協程,我之前也是在這個地方困惑了很久,前面說的大多日常用到過,也清楚一些原理,關于協程用到的就少了,我們來分析下吧。
直接看一下協程的例子:
function asnycJob() { // ...其他代碼 var f = yield readFile(fileA); // ...其他代碼}
阮一峰老師的原話:
上面代碼的函數 asyncJob 是一個協程,它的奧妙就在其中的 yield 命令。它表示執行到此處,執行權將交給其他協程。也就是說,yield命令是異步兩個階段的分界線。 協程遇到 yield 命令就暫停,等到執行權返回,再從暫停的地方繼續往后執行。它的最大優點,就是代碼的寫法非常像同步操作,如果去除yield命令,簡直一模一樣。
之前沒理解的原因就是沒好好讀這兩句話,今認真看了一下,茅塞頓開。重要的有這么幾點
首先asnycJob這個方法就是一個協程
yield相當于return,會返回當前程序的執行狀態
當執行到yield,程序掛起等待返回后繼續執行。
掛起這段時間去執行其他協程函數
Generator函數是ES6對協程函數的實現,
Generator函數的特點就是可以暫停代碼執行。
跟協程函數一樣,遇到yield關鍵字就暫停代碼執行,
跟普通函數的區別在于Generator函數不會反悔結果,而是返回指針對象,
通過指針的next方法移動指針指向下一個yield關鍵字位置。
也就是說Generator函數的分階段執行是由next方法控制的。
使用了Generator函數之后會對我們的代碼有多大的改變呢?
fangction* gen(){ var url = ’user/get/info’; var data = yield $.get({url:url}); console.log(data.userName);}
你不需要擔心遠程接口的返回時機,完全按照同步的方式寫代碼就行。
但是也有缺點,Generator函數把一步操作做的很簡潔,但對流程的管理卻不方便,
上面的例子如何執行?
var g = gen();g.next();g.next();
next 方法的作用是分階段執行 Generator 函數。每次調用 next 方法,會返回一個對象,
表示當前階段的信息( value 屬性和 done 屬性)。value 屬性是 yield 語句后面表達式的值,表示當前階段的值;
done 屬性是一個布爾值,表示 Generator 函數是否執行完畢,即是否還有下一個階段。
你需要執行兩次.next方法,來將你的Generator函數執行完畢。
關于如何自動化異步任務的流程管理,就需要co,thunk,async的幫助了
原文:Generator 函數的含義與用法
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。
更多關于JavaScript相關內容可查看本站專題:《JavaScript常用函數技巧匯總》、《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》及《JavaScript數學運算用法總結》
希望本文所述對大家JavaScript程序設計有所幫助。
相關文章:
