成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你是否對JS中的Generator及協程真正理解?

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

[[347310]]

本文轉載自微信公眾號「前端三元同學」,作者神三元。轉載本文請聯系前端三元同學公眾號。  

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

生成器執行流程

什么是生成器函數?

生成器是一個帶星號的"函數"(注意:它并不是真正的函數),可以通過yield關鍵字暫停執行和恢復執行的

舉個例子:

  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() // 阻塞住,不會執行任何語句 
  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 } 

由此可以看到,生成器的執行有這樣幾個關鍵點:

  1. 調用 gen() 后,程序會阻塞住,不會執行任何語句。
  2. 調用 g.next() 后,程序繼續執行,直到遇到 yield 程序暫停。
  3. next 方法返回一個對象, 有兩個屬性: value 和 done。value 為當前 yield 后面的結果,done 表示是否執行完,遇到了return 后,done 會由false變為true。

yield* 語法

當一個生成器要調用另一個生成器時,使用 yield* 就變得十分方便。比如下面的例子:

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

我們想要按照1234的順序執行,如何來做呢?

在 gen1 中,修改如下:

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

這樣修改之后,之后依次調用next即可。

生成器實現機制——協程

可能你會比較好奇,生成器究竟是如何讓函數暫停, 又會如何恢復的呢?接下來我們就來對其中的執行機制——協程一探究竟。

什么是協程?

協程是一種比線程更加輕量級的存在,協程處在線程的環境中,一個線程可以存在多個協程,可以將協程理解為線程中的一個個任務。不像進程和線程,協程并不受操作系統的管理,而是被具體的應用程序代碼所控制。

協程的運作過程

那你可能要問了,JS 不是單線程執行的嗎,開這么多協程難道可以一起執行嗎?

答案是:并不能。一個線程一次只能執行一個協程。比如當前執行 A 協程,另外還有一個 B 協程,如果想要執行 B 的任務,就必須在 A 協程中將JS 線程的控制權轉交給 B協程,那么現在 B 執行,A 就相當于處于暫停的狀態。

舉個具體的例子:

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

在這個過程中,A 將執行權交給 B,也就是 A 啟動 B,我們也稱 A 是 B 的父協程。因此 B 當中最后return 100其實是將 100 傳給了父協程。

需要強調的是,對于協程來說,它并不受操作系統的控制,完全由用戶自定義切換,因此并沒有進程/線程上下文切換的開銷,這是高性能的重要原因。

 

責任編輯:武曉燕 來源: 前端三元同學
相關推薦

2018-11-27 09:45:54

2024-12-03 15:15:22

2023-11-26 18:35:25

Python編程語言

2023-12-24 12:56:36

協程

2021-09-16 09:59:13

PythonJavaScript代碼

2020-11-30 08:25:41

程序員高并發協程

2019-06-14 14:58:58

虛擬文件系統Linux

2023-11-17 11:36:59

協程纖程操作系統

2022-05-24 15:09:13

機器人深度學習人工智能

2023-11-28 12:25:02

多線程安全

2022-06-30 09:10:33

NoSQLHBaseRedis

2016-12-20 10:55:52

深度學習

2021-04-28 09:08:23

Kotlin協程代碼

2020-02-24 10:39:55

Python函數線程池

2022-09-06 11:13:16

接口PipelineHandler

2024-02-05 09:06:25

Python協程Asyncio庫

2025-06-26 04:10:00

2019-12-26 09:15:44

網絡IOLinux

2024-06-27 07:56:49

2020-07-07 10:03:27

Android 協程開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.国产精品| av一区二区三区在线观看 | 久久久久久成人 | 亚洲网站在线播放 | 国产色| 性网站免费 | 亚洲国产成人精品久久久国产成人一区 | 一级片在线视频 | 高清久久久 | 精品av| 伊人无码高清 | 999国产视频| 欧美精品国产一区二区 | 蜜桃视频在线观看免费视频网站www | 美女高潮网站 | 国产色婷婷精品综合在线手机播放 | 亚洲综合区 | 国产无套一区二区三区久久 | 欧美性一级| 韩国精品在线 | 国外成人在线视频 | 最新一级毛片 | 久久久久国产 | 国产一伦一伦一伦 | 欧美精品区 | 超碰在线久 | 国产 日韩 欧美 在线 | 国产精品黄色 | 欧美视频第三页 | 国产精品久久久久免费 | 国产a级毛毛片 | 视频一区二区三区四区五区 | 玖玖在线精品 | 91aiai| 99在线观看视频 | 国产精品美女久久久久久免费 | 国产在线观看 | 久久久久久免费毛片精品 | 一区二区三区欧美 | 国产午夜精品久久久久 | 日韩在线精品视频 |