日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
你是否對(duì)JS中的Generator及協(xié)程真正理解?

本文轉(zhuǎn)載自微信公眾號(hào)「前端三元同學(xué)」,作者神三元。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端三元同學(xué)公眾號(hào)。  

我們注重客戶(hù)提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好成都做網(wǎng)站、網(wǎng)站建設(shè)服務(wù),我們努力開(kāi)拓更好的視野,通過(guò)不懈的努力,成都創(chuàng)新互聯(lián)公司贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶(hù)。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),微信小程序,網(wǎng)站開(kāi)發(fā),技術(shù)開(kāi)發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開(kāi)發(fā)工程師。

生成器(Generator)是 ES6 中的新語(yǔ)法,相對(duì)于之前的異步語(yǔ)法,上手的難度還是比較大的。因此這里我們先來(lái)好好熟悉一下 Generator 語(yǔ)法。

生成器執(zhí)行流程

什么是生成器函數(shù)?

生成器是一個(gè)帶星號(hào)的"函數(shù)"(注意:它并不是真正的函數(shù)),可以通過(guò)yield關(guān)鍵字暫停執(zhí)行和恢復(fù)執(zhí)行的

舉個(gè)例子:

 
 
 
  1. function* gen() { 
  2.   console.log("enter"); 
  3.   let a = yield 1; 
  4.   let b = yield (function () {return 2})(); 
  5.   return 3; 
  6. var g = gen() // 阻塞住,不會(huì)執(zhí)行任何語(yǔ)句 
  7. console.log(typeof g)  // object  看到了嗎?不是"function" 
  8.  
  9. console.log(g.next())   
  10. console.log(g.next())   
  11. console.log(g.next())   
  12. console.log(g.next())  
  13.  
  14.  
  15. // enter 
  16. // { value: 1, done: false } 
  17.  
  18. // { value: 2, done: false } 
  19. // { value: 3, done: true } 
  20. // { value: undefined, done: true } 

由此可以看到,生成器的執(zhí)行有這樣幾個(gè)關(guān)鍵點(diǎn):

  1. 調(diào)用 gen() 后,程序會(huì)阻塞住,不會(huì)執(zhí)行任何語(yǔ)句。
  2. 調(diào)用 g.next() 后,程序繼續(xù)執(zhí)行,直到遇到 yield 程序暫停。
  3. next 方法返回一個(gè)對(duì)象, 有兩個(gè)屬性: value 和 done。value 為當(dāng)前 yield 后面的結(jié)果,done 表示是否執(zhí)行完,遇到了return 后,done 會(huì)由false變?yōu)閠rue。

yield* 語(yǔ)法

當(dāng)一個(gè)生成器要調(diào)用另一個(gè)生成器時(shí),使用 yield* 就變得十分方便。比如下面的例子:

 
 
 
  1. function* gen1() { 
  2.     yield 1; 
  3.     yield 4; 
  4. function* gen2() { 
  5.     yield 2; 
  6.     yield 3; 

我們想要按照1234的順序執(zhí)行,如何來(lái)做呢?

在 gen1 中,修改如下:

 
 
 
  1. function* gen1() { 
  2.     yield 1; 
  3.     yield* gen2(); 
  4.     yield 4; 

這樣修改之后,之后依次調(diào)用next即可。

生成器實(shí)現(xiàn)機(jī)制——協(xié)程

可能你會(huì)比較好奇,生成器究竟是如何讓函數(shù)暫停, 又會(huì)如何恢復(fù)的呢?接下來(lái)我們就來(lái)對(duì)其中的執(zhí)行機(jī)制——協(xié)程一探究竟。

什么是協(xié)程?

協(xié)程是一種比線程更加輕量級(jí)的存在,協(xié)程處在線程的環(huán)境中,一個(gè)線程可以存在多個(gè)協(xié)程,可以將協(xié)程理解為線程中的一個(gè)個(gè)任務(wù)。不像進(jìn)程和線程,協(xié)程并不受操作系統(tǒng)的管理,而是被具體的應(yīng)用程序代碼所控制。

協(xié)程的運(yùn)作過(guò)程

那你可能要問(wèn)了,JS 不是單線程執(zhí)行的嗎,開(kāi)這么多協(xié)程難道可以一起執(zhí)行嗎?

答案是:并不能。一個(gè)線程一次只能執(zhí)行一個(gè)協(xié)程。比如當(dāng)前執(zhí)行 A 協(xié)程,另外還有一個(gè) B 協(xié)程,如果想要執(zhí)行 B 的任務(wù),就必須在 A 協(xié)程中將JS 線程的控制權(quán)轉(zhuǎn)交給 B協(xié)程,那么現(xiàn)在 B 執(zhí)行,A 就相當(dāng)于處于暫停的狀態(tài)。

舉個(gè)具體的例子:

 
 
 
  1. function* A() { 
  2.   console.log("我是A"); 
  3.   yield B(); // A停住,在這里轉(zhuǎn)交線程執(zhí)行權(quán)給B 
  4.   console.log("結(jié)束了"); 
  5. function B() { 
  6.   console.log("我是B"); 
  7.   return 100;// 返回,并且將線程執(zhí)行權(quán)還給A 
  8. let gen = A(); 
  9. gen.next(); 
  10. gen.next(); 
  11.  
  12. // 我是A 
  13. // 我是B 
  14. // 結(jié)束了 

在這個(gè)過(guò)程中,A 將執(zhí)行權(quán)交給 B,也就是 A 啟動(dòng) B,我們也稱(chēng) A 是 B 的父協(xié)程。因此 B 當(dāng)中最后return 100其實(shí)是將 100 傳給了父協(xié)程。

需要強(qiáng)調(diào)的是,對(duì)于協(xié)程來(lái)說(shuō),它并不受操作系統(tǒng)的控制,完全由用戶(hù)自定義切換,因此并沒(méi)有進(jìn)程/線程上下文切換的開(kāi)銷(xiāo),這是高性能的重要原因。


網(wǎng)站題目:你是否對(duì)JS中的Generator及協(xié)程真正理解?
URL網(wǎng)址:http://www.5511xx.com/article/dhjcphg.html