⑴ Web前端面試指導(三十二):同步和非同步有什麼區別
同步就是發出請求後,等到伺服器返回結果,才繼續執行下一步,非同步則是不等伺服器返回,直接並行執行下一步,伺服器返回結果會通過處理回調函數執行
⑵ springboot框架開發的rest api工程,非同步請求方法同步調用執行,怎麼做
1、controller本身就是單例的,非線程安全,多線程會共用對象
2、controller不要涉及業務層,從其屬性來看,控制層來連接請求觸發服務
3、根據需求,兩種方法都可行,只要不在controller層處理業務;
4、如果三個方法都是需要返回數據的,建議各自寫各自的controller層,清晰明白;其實,如果三個方法業務性質一樣,也可以封裝起來,通過參數判斷具體執行那部分代碼
⑶ 前端的Promise是幹啥的
Promise是非同步編程的一種解決方案,可以替代傳統的解決方案--回調函數和事件。ES6統一了用法,並原生提供了Promise對象。作為對象,Promise有以下兩個特點:
(1)對象的狀態不受外界影響。
(2)一旦狀態改變了就不會在變,也就是說任何時候Promise都只有一種狀態。
可以通過Promise的構造函數創建Promise對象。
varpromise=newPromise(function(resolve,reject)setTimeout(function(){
console.log("helloworld");},2000);
});
Promise構造函數接收一個函數作為參數,該函數的兩個參數是resolve,reject,它們由JavaScript引擎提供。其中resolve函數的作用是當Promise對象轉移到成功,調用resolve並將操作結果作為其參數傳遞出去;reject函數的作用是單Promise對象的狀態變為失敗時,將操作報出的錯誤作為其參數傳遞出去。如下面的代碼:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}
greet().then(v=>{console.log(v);//*
})
上面的*行的輸出結果就是greet的值,也就是resolve()傳遞出來的參數。
注意:創建一個Promise對象會立即執行裡面的代碼,所以為了更好的控制代碼的運行時刻,可以將其包含在一個函數中,並將這個Promise作為函數的返回值。
Promise的then方法
promise的then方法帶有以下三個參數:成功回調,失敗回調,前進回調,一般情況下只需要實現第一個,後面是可選的。Promise中最為重要的是狀態,通過then的狀態傳遞可以實現回調函數鏈式操作的實現。先執行以下代碼:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}varp=greet().then(v=>{console.log(v);
})console.log(p);
⑷ js 如何判斷是非同步請求還是普通請求
這是根據請求時的參數來決定的啊,如果async為true就是非同步請求,為false就是同步請求。也就是說,是否非同步請求是由前端決定的,後台程序是不作區分一視同仁處理的。前端如果是以同步方式發出請求,它就會阻塞程序,等待後台返回數據再繼續運行;而非同步方式的話,就會立刻返回,繼續執行其他代碼,當後台返回數據時再以回調函數的形式進行處理。既然同步非同步是由前端決定的,那麼前端的js自然就知道如何來處理這個請求結果啦。
⑸ 前端開發中如何實現非同步編程
非同步編程其實很常見,特別是在出線Node.js之後,非同步編程更是讓很多開發者受益。那麼回到最初的地方,傳統的前端開發中如何實現非同步編程呢?下面列舉了js實現非同步編程的四種方式。
方法一:使用回調函數
方法二:事件監聽
可以定義一個事件,並為這個事件設定處理函數。這樣只有當這個時間發生的情況下,對應的處理函數才會被執行。
方法三:事件的發布/訂閱
這個模式在NodeJS以及其他JS框架中都有實現,是一個非常常用的非同步編程方式。具體的原理及實現方法可以參考我之前的博客:http://blog.csdn.net/fareise/article/details/52198877《 Node中EventEmitter以及如何實現JavaScript中的訂閱/發布模式》,裡面有比較詳細的解析。
方法四:Promise模式
ES6中提供了原生的Promise對象,這個模式最開始只是一個構想,後來由一些框架庫實現。Promise對象代表了未來才會知道結果的事件。
Promise的基本思路就是,將需要非同步執行的事件儲存起來,然後根據非同步事件之行後的結果狀態執行下一步的操作。具體的Promise對象的原理和ES6中的使用方法將在下一篇文章中更加深入的進行介紹。
⑹ 關於外頻和內存的非同步和同步問題
沒有必要換內存,因為你的內存沒有任何問題.
內存的運行頻率是和你的前端匯流排同步的.如FSB400 內存就266 FSB533 內存就是333 FSB800 內存就是400 的.如果非同步可能會造成不穩定.我的電腦就是這樣.我的是FSB533 我的DDR400 就會降到333 如果要超頻我的電腦會沒有聲音.
一般來說SP2800裝機的時候都會選擇超頻,SP2800 1.8GHZ,你去看一下你是不是1.8GHZ
內存非同步需要主板的支持.
⑺ 怎麼能讓前端匯流排和內存同步
Front Side Bus,簡寫為FSB,前端匯流排
什麼是前端匯流排?不是超頻的方法之一,也不是用來超頻的。
我們知道,電腦有許多配件,配件不同,速度也就不同。在286、386和早期的486電腦里,CPU的速度不是太高,和內存保持一樣的速度。後來隨著CPU速度的飛速提升,內存由於電氣結構關系,無法象CPU那樣提升很高的速度(就算現在內存達到400、533,但跟CPU的幾個G的速度相比,根本就不是一個級別的),於是造成了內存和CPU之間出現了速度差異,這時就提出一個CPU的主頻、倍頻和外頻的概念,外頻顧名思義就是CPU外部的頻率,也就是內存的頻率,CPU以這個頻率來與內存聯系。CPU的主頻就是CPU內部的實際運算速度,主頻肯定是比外頻高的,高一定的倍數,這個數就是倍頻。舉個例子,你從電腦垃圾堆里揀到一個被拋棄的INTEL 486 CPU,上面印著486 DX/2 66。這個486的CPU的主頻是66MHZ,DX/2代表是2倍頻的,於是算出CPU的外頻是33MZ,也就是內存的工作頻率,這同時也是前端匯流排FSB的頻率。因為CPU是通過前端匯流排來與內存發生聯系的,所以內存的工作頻率(或者說外頻也行)就是前端匯流排的頻率。剛才這個垃圾堆里的486 CPU,前端匯流排的頻率就是33MZ。這樣的前端匯流排結構一直延續到486之後的奔騰(俗話說的586)、奔騰2、奔騰3,例如一顆奔3 933MHZ的CPU,外頻133,也就是說它的前端匯流排是133MHZ,內存工作頻率也是133。
到了奔騰4年代,內存和CPU的工作模式發生了改變,前端匯流排的概念也變得有些復雜。奔騰4 CPU採用了Quad Pumped(4倍並發)技術,該技術可以使系統匯流排在一個時鍾周期內傳送4次數據,也就是傳輸效率是原來的4倍,相當於用了4條原來的前端匯流排來和內存發生聯系。在外頻仍然是133MHZ的時候,前端匯流排的速度增加4倍變成了133X4=533MHZ,當外頻升到200MHZ,前端匯流排變成800MHZ,所以你會看到533前端匯流排的P4和800前端匯流排的P4,就是這樣來的。他們的實際外頻只有133和200,但由於人們保留了以前老的概念——前端匯流排就是外頻,所以習慣了這樣的叫法:533外頻的P4和800外頻的P4。其實還是叫533前端匯流排或533 FSB的P4比較合適。
那內存的情況怎麼樣呢?外頻不完全等於前端匯流排了,那外頻還等於內存的頻率嗎?內存發展到了DDR,跟原來相比,一個時鍾周期內可以傳送比原來多一倍的數據,DDR就是DOUBLE DATA RATE的縮寫,意思就是雙倍的數據傳輸速率。在133MHZ的外頻下,DDR的傳輸速度是266,外頻提高到200MHZ的時候,DDR的傳輸速度是400,DDR266的內存和DDR400的內存就是這個意思。
再看一下現在外頻、內存頻率、CPU的前端匯流排的的關系。在以前P3的時候,133的外頻,內存的頻率就是133,CPU的前端匯流排也是133,三者是一回事。現在P4的CPU,在133的外頻下,前端匯流排達到了533MHZ,內存頻率是266(DDR266)。問題出現了,前端匯流排是CPU與內存發生聯系的橋梁,P4這時候的前端匯流排達到533之高,而內存只有266的速度,內存比CPU的前端匯流排慢了一半,理論上CPU有一半時間要等內存傳數據過來才能處理數據,等於內存拖了CPU的後腿。這樣的情況的確存在的,845和848的主板就是這樣。於是提出一個雙通道內存的概念,兩條內存使用兩條通道一起工作,一起提供數據,等於速度又增加一倍,兩條DDR266就有266X2=533的速度,剛好是P4 CPU的前端匯流排速度,沒有拖後腿的問題。外頻提升到200的時候,CPU前端匯流排變為800,兩條DDR400內存組成雙通道,內存傳輸速度也是800了。所以要P4發揮好,一定要用雙通道內存,865以上的主板都提供這個功能。但845和848主板就沒有內存雙通道功能了。
剛才說的是INTEL P4的FSB概念,它的對手AMD的CPU有所不同。
舊的462針腳的AMD CPU,採用ev6前端匯流排,相當於外頻的兩倍,也就是133外頻時,AMD 462腳的CPU的FSB是266,使用DDR266內存和他搭配就剛剛好,如果用兩條DDR266做成雙通道,雖然內存有533的傳輸速度,但對於266的FSB,作用不大,所以雙通道內存對CPU的幫助不明顯。
新的AMD 754/939 64位CPU,內部就集成了內存管理器(以前內存管理器在主板心片里),所以AMD 64位CPU的前端匯流排FSB頻率與CPU實際頻率一致。
★FSB只指CPU與北橋晶元之間的數據傳輸速率,又稱前端匯流排。FSB=CPU外頻*4。
這個參數指的就是前端匯流排的頻率,它是處理器與主板交換數據的通道,既然是通道,那就是越大越好,現在主流中最高的FSB是800M,向下有533M、400M和333M等幾種,它們價格是遞減的。
FSB(或是FrontSideBus,前端匯流排)是超頻最容易和最常見的方法之一。FSB是CPU與系統其它部分連接的速度。它還影響內存時鍾,那是內存運行的速度。一般而言,對FSB和內存時鍾兩者來說越高等於越好。然而,在某些情況下這不成立。例如,讓內存時鍾比FSB運行得快根本不會有真正的幫助。同樣,在AthlonXP系統上,讓FSB運行在更高速度下而強制內存與FSB不同步(使用稍後將討論的內存分頻器)對性能的阻礙將比運行在較低FSB及同步內存下要嚴重得多。
FSB在Athlon和P4系統上涉及到不同的方法。在Athlon這邊,它是DDR匯流排,意味著如果實際時鍾是200MHz的話,那就是運行在400MHz下。在P4上,它是「四芯的」,所以如果實際時鍾是相同的200MHz的話,就代表800MHz。這是Intel的市場策略,因為對一般用戶來說,越高等於越好。Intel的「四芯」FSB實際上具有一個現實的優勢,那就是以較小的性能損失為代價允許P4晶元與內存不同步運行。每個時鍾越高的周期速度使得它越有機會讓內存周期與CPU周期重合,那等同於越好的性能。 Front Side Bus,簡寫為FSB,前端匯流排
什麼是前端匯流排?不是超頻的方法之一,也不是用來超頻的。
我們知道,電腦有許多配件,配件不同,速度也就不同。在286、386和早期的486電腦里,CPU的速度不是太高,和內存保持一樣的速度。後來隨著CPU速度的飛速提升,內存由於電氣結構關系,無法象CPU那樣提升很高的速度(就算現在內存達到400、533,但跟CPU的幾個G的速度相比,根本就不是一個級別的),於是造成了內存和CPU之間出現了速度差異,這時就提出一個CPU的主頻、倍頻和外頻的概念,外頻顧名思義就是CPU外部的頻率,也就是內存的頻率,CPU以這個頻率來與內存聯系。CPU的主頻就是CPU內部的實際運算速度,主頻肯定是比外頻高的,高一定的倍數,這個數就是倍頻。舉個例子,你從電腦垃圾堆里揀到一個被拋棄的INTEL 486 CPU,上面印著486 DX/2 66。這個486的CPU的主頻是66MHZ,DX/2代表是2倍頻的,於是算出CPU的外頻是33MZ,也就是內存的工作頻率,這同時也是前端匯流排FSB的頻率。因為CPU是通過前端匯流排來與內存發生聯系的,所以內存的工作頻率(或者說外頻也行)就是前端匯流排的頻率。剛才這個垃圾堆里的486 CPU,前端匯流排的頻率就是33MZ。這樣的前端匯流排結構一直延續到486之後的奔騰(俗話說的586)、奔騰2、奔騰3,例如一顆奔3 933MHZ的CPU,外頻133,也就是說它的前端匯流排是133MHZ,內存工作頻率也是133。
到了奔騰4年代,內存和CPU的工作模式發生了改變,前端匯流排的概念也變得有些復雜。奔騰4 CPU採用了Quad Pumped(4倍並發)技術,該技術可以使系統匯流排在一個時鍾周期內傳送4次數據,也就是傳輸效率是原來的4倍,相當於用了4條原來的前端匯流排來和內存發生聯系。在外頻仍然是133MHZ的時候,前端匯流排的速度增加4倍變成了133X4=533MHZ,當外頻升到200MHZ,前端匯流排變成800MHZ,所以你會看到533前端匯流排的P4和800前端匯流排的P4,就是這樣來的。他們的實際外頻只有133和200,但由於人們保留了以前老的概念——前端匯流排就是外頻,所以習慣了這樣的叫法:533外頻的P4和800外頻的P4。其實還是叫533前端匯流排或533 FSB的P4比較合適。
那內存的情況怎麼樣呢?外頻不完全等於前端匯流排了,那外頻還等於內存的頻率嗎?內存發展到了DDR,跟原來相比,一個時鍾周期內可以傳送比原來多一倍的數據,DDR就是DOUBLE DATA RATE的縮寫,意思就是雙倍的數據傳輸速率。在133MHZ的外頻下,DDR的傳輸速度是266,外頻提高到200MHZ的時候,DDR的傳輸速度是400,DDR266的內存和DDR400的內存就是這個意思。
再看一下現在外頻、內存頻率、CPU的前端匯流排的的關系。在以前P3的時候,133的外頻,內存的頻率就是133,CPU的前端匯流排也是133,三者是一回事。現在P4的CPU,在133的外頻下,前端匯流排達到了533MHZ,內存頻率是266(DDR266)。問題出現了,前端匯流排是CPU與內存發生聯系的橋梁,P4這時候的前端匯流排達到533之高,而內存只有266的速度,內存比CPU的前端匯流排慢了一半,理論上CPU有一半時間要等內存傳數據過來才能處理數據,等於內存拖了CPU的後腿。這樣的情況的確存在的,845和848的主板就是這樣。於是提出一個雙通道內存的概念,兩條內存使用兩條通道一起工作,一起提供數據,等於速度又增加一倍,兩條DDR266就有266X2=533的速度,剛好是P4 CPU的前端匯流排速度,沒有拖後腿的問題。外頻提升到200的時候,CPU前端匯流排變為800,兩條DDR400內存組成雙通道,內存傳輸速度也是800了。所以要P4發揮好,一定要用雙通道內存,865以上的主板都提供這個功能。但845和848主板就沒有內存雙通道功能了。
剛才說的是INTEL P4的FSB概念,它的對手AMD的CPU有所不同。
舊的462針腳的AMD CPU,採用ev6前端匯流排,相當於外頻的兩倍,也就是133外頻時,AMD 462腳的CPU的FSB是266,使用DDR266內存和他搭配就剛剛好,如果用兩條DDR266做成雙通道,雖然內存有533的傳輸速度,但對於266的FSB,作用不大,所以雙通道內存對CPU的幫助不明顯。
新的AMD 754/939 64位CPU,內部就集成了內存管理器(以前內存管理器在主板心片里),所以AMD 64位CPU的前端匯流排FSB頻率與CPU實際頻率一致。
★FSB只指CPU與北橋晶元之間的數據傳輸速率,又稱前端匯流排。FSB=CPU外頻*4。
這個參數指的就是前端匯流排的頻率,它是處理器與主板交換數據的通道,既然是通道,那就是越大越好,現在主流中最高的FSB是800M,向下有533M、400M和333M等幾種,它們價格是遞減的。
FSB(或是FrontSideBus,前端匯流排)是超頻最容易和最常見的方法之一。FSB是CPU與系統其它部分連接的速度。它還影響內存時鍾,那是內存運行的速度。一般而言,對FSB和內存時鍾兩者來說越高等於越好。然而,在某些情況下這不成立。例如,讓內存時鍾比FSB運行得快根本不會有真正的幫助。同樣,在AthlonXP系統上,讓FSB運行在更高速度下而強制內存與FSB不同步(使用稍後將討論的內存分頻器)對性能的阻礙將比運行在較低FSB及同步內存下要嚴重得多。
FSB在Athlon和P4系統上涉及到不同的方法。在Athlon這邊,它是DDR匯流排,意味著如果實際時鍾是200MHz的話,那就是運行在400MHz下。在P4上,它是「四芯的」,所以如果實際時鍾是相同的200MHz的話,就代表800MHz。這是Intel的市場策略,因為對一般用戶來說,越高等於越好。Intel的「四芯」FSB實際上具有一個現實的優勢,那就是以較小的性能損失為代價允許P4晶元與內存不同步運行。每個時鍾越高的周期速度使得它越有機會讓內存周期與CPU周期重合,那等同於越好的性能。
⑻ 在BIOS里怎麼設置CPU外頻與內存頻率的同步和非同步
主板不同各有差異,我的是技嘉的,CPU外頻先把CPU HOST CLOCK CONTROL改為ENABLED,然後CPU HOST FREQUENCY(MHZ)就是外頻,如現在200可改為233,慢慢一點點升,多了可能就不能開機了。內存頻率在CPU英文的下面叫做SYSTEM MERORY MULTIPLIER,默認是AUTO,是同步,非同步裡面可改為2 或2.5或 3之類的數字。
⑼ 怎樣用JS實現非同步轉同步
源起
小飛是一名剛入行前端不久的新人,因為進到了某個大公司,儼然成為了學弟學妹眼中'大神',大家遇到js問題都喜歡問他,這不,此時他的qq彈出了這樣一條消息
"hi,大神在嗎?我有個問題想問,現在我們的代碼裡面有這樣的東西,可是得不到正確的返回結果
1234567functiongetDataByAjax () {return$.ajax(...postParam)}vardata = getDataByAjax()if(data) {console.log(data.info)}"哦,你這里是非同步調用,不能直接獲得返回值,你要把if語句寫到回調函數中",小飛不假思索的說到,對於一個『專業』的fe來說,這根本不是一個問題。
「可是我希望只是改造getDataByAjax這個方法,讓後面的代碼成立。」
「研究這個沒有意義,非同步是js的精髓,同步的話會阻塞js調用,超級慢的,但是你要一再堅持的話,用async:true就好了」
「不愧是大神,我回去立刻試一試,么么噠」
兩天後,她哭喪著臉登上了qq
「試了一下你的方法,但是根本行不通,哭~~」
「別急,我看看你這個postParam的參數行嗎」
"這是一個jsonp請求啊,老掉牙的東西了,,jsonp請求是沒有辦法同步的"
「我知道jsonp請求的原理是通過script標簽實現的,但是,你看,script也是支持同步的呀,你看tags/attscriptasync.asp」
「額,那可能是jquery沒有實現吧,哈哈」
「大神,你能幫我實現一個jsonp的同步調用方式嘛,拜託了(星星眼)」
雖然他有點奇怪jquery為什麼沒有實現,但是既然w3school的標准擺在那裡,碼兩行代碼又沒什麼,
額,運行起來結果竟然是undefined!w3cshool的文檔竟然也不準,還權威呢,我看也不怎麼著,小飛暗自想到。
「剛才試了一下,w3school文檔上寫的有問題,這個非同步屬性根本就是錯的」
「可是我剛還試過一次這個,我確認是好的呀」
(有興趣的同學可以實現以下兩個js,並且加上async的標簽進行嘗試。)
「這個,我就搞不清楚了」,小飛訕訕的說到
對方已離線
抽象
關於這個問題,相信不只是小飛,很多人都難以解答。為什麼ajax可以做到同步,但jsonp不行,推廣到nodejs上,為什麼readFile也可以做到同步(readFileSync),但有的庫卻不行。
(至於script的async選項我們暫時避而不談,是因為現在的知識維度暫時還不夠,但是不要著急,下文中會給出明確的解釋)
現在,讓我們以計算機科學的角度抽象這個問題:
我們是否可以將非同步代碼轉化為同步代碼呢?(ASYNCCALL => SYNCCALL)
既然是抽象問題,那麼我們就可以不從工程角度/性能角度/實現語言等等等方面來看(同步比非同步效率低下),每增加一個維度,復雜程度將以幾何爆炸般增長下去。
首先,我們來明確一點,==在計算機科學領域==同步和非同步的定義
同步(英語:Synchronization),指對在一個系統中所發生的事件(event)之間進行協調,在時間上出現一致性與統一化的現象。在系統中進行同步,也被稱為及時(in time)、同步化的(synchronous、in sync)。--摘自網路
非同步的概念和同步相對。即時間不一致,不統一
明確了這一點,我們可以藉助甘特圖來表示同步和非同步
注意看我們標紅的地方,如果你完成了小測驗1,就會得到和這張圖一致的順序
==同步執行的代碼片段必然在非同步之前。==
所以,無論從理論還是實際出發,我們都不得不承認,在js中,把非同步方法改成同步方法這個命題是水月鏡花
哦對了,最後還需要解釋一下最開始我們埋下的坑, 為什麼jsonp中的async沒有生效,現在解釋起來真的是相當輕松,即document.appendChild的動作是交由dom渲染線程完成的,所謂的async阻塞的是dom的解析,而非js引擎的阻塞。實際上,在async獲取資源後,與js引擎的交互依舊是push taskQueue的動作,也就是我們所說的async call
推薦閱讀: 關於dom解析請大家參考webkit技術內幕第九章資源載入部分
峰迴路轉
相信很多新潮的同學已經開始運用切了async/await語法,在下面的語法中,getAjax1和console之間的具有同步的特性
1234asyncfunction() {vardata = await getAjax1()console.log(data)}講完了event loop和非同步的本質,我們來重新審視一下async/await。
老天,這段代碼親手推翻了==同步執行的代碼片段必然在非同步之前。== 的黃金定律!
驚不驚喜,意不意外,這在我們的模型里如同三體里的質子一樣的存在。我們重新審視了一遍上面的模型,實在找不到漏洞,找不到任何可以推翻的點,所以真的必須承認,async/await絕對是一個超級神奇的魔法。
到這里來看我們不得不暫時放棄前面的推論,從async/await本身來看這個問題
相信很多人都會說,async/await是CO的語法糖,CO又是generator/promise的語法糖,好的,那我們不妨去掉這層語法糖,來看看這種代碼的本質, 關於CO,讀的人太多了,我實在不好老生常談,可以看看這篇文章,咱們就直接繞過去了,這里給出一個簡易的實現
/5800210.html
終於,我們發現了問題的關鍵,如果單純的看wait生成器(注意,不是普通的函數),是不是覺得非常眼熟。這就是我們最開始提出的spinlock偽代碼!!!
這個已經被我們完完全全的否定過了,js不可能存在自旋鎖,事出反常必有妖,是的,yield和*就是表演async/await魔法的妖精。
generator和yield字面上含義。Gennerator叫做生成器,yield這塊ruby,python,js等各種語言界爭議很大,但是大多數人對於『讓權』這個概念是認同的(以前看到過maillist上面的爭論,但是具體的內容已經找不到了)
擴展閱讀---ruby元編程 閉包章節yield(ruby語義下的yield)
所謂讓權,是指cpu在執行時讓出使用權利,操作系統的角度來看就是『掛起』原語,在eventloop的語義下,似乎是暫存起當時正在執行的代碼塊(在我們的eventloop裡面對應runPart),然後順序的執行下一個程序塊。
我們可以修改eventloop來實現讓權機制
小測驗2 修改eventloop使之支持yield原語
至此,通過修改eventloop模型固然可以解決問題,但是,這並不能被稱之為魔法。
和諧共存的世界
實際上通過babel,我們可以輕松的降級使用yield,(在es5的世界使用讓權的概念!!)
看似不可能的事情,現在,讓我們撿起曾經論證過的
==同步執行的代碼片段必然在非同步之前。== 這個定理,在此基礎上進行進行逆否轉化
==在非同步代碼執行之後的代碼必然不是同步執行的(非同步的)。==
這是一個圈子裡人盡皆知的話,但直到現在他才變得有說服力(我們繞了一個好長的圈子)
現在,讓我們允許使用callback,不使用generator/yield的情況下完成一個wait generator相同的功能!!!
太棒了,我們成功的完成了generator到function的轉化(雖然成本高昂),同時,這段代碼本身也解釋清楚了generator的本質,高階函數,片段生成器,或者直接叫做函數生成器!這和scip上的翻譯完全一致,同時擁有自己的狀態(有限狀態機)
推薦閱讀 計算機程序的構造和解釋 第一章generator部分
小測驗3 實際上我們提供的解決方式存在缺陷,請從作用域角度談談
其實,在不知不覺中,我們已經重新發明了計算機科學中大名鼎鼎的CPS變換
Continuation-passing_style
最後的最後,容我向大家介紹一下facebook的CPS自動變換工具--regenerator。他在我們的基礎上修正了作用域的缺陷,讓generator在es5的世界裡自然優雅。我們向facebook脫帽致敬!!egenerator
後記
同步非同步 可以說是整個圈子裡面最喜歡談論的問題,但是,談來談去,似乎絕大多數變成了所謂的『約定俗稱』,大家意味追求新技術的同時,卻並不關心新技術是如何在老技術上傳承發展的,知其然而不知其所以然,人雲亦雲的寫著似是而非的js。
==技術,不應該浮躁==
PS: 最大的功勞不是CO,也不是babel。regenerator的出現比babel早幾個月,而且最初的實現是基於esprima/recast的,關於resprima/recast,國內似乎了解的並不多,其實在babel剛剛誕生之際, esprima/esprima-fb/acron 以及recast/jstransfrom/babel-generator幾大族系圍繞著react產生過一場激烈的斗爭,或許將來的某一天,我會再從實現細節上談一談為什麼babel笑到了最後~~~~