"Code tailor",爲前端開發者提供技術相關資訊以及系列基礎文章,微信關注「小和山的菜鳥們」公衆號,及時獲取最新文章。
在開始學習以前,咱們想要告訴您的是,本文章是對阮一峯《ECMAScript6 入門》一書中 "Generator" 章節的總結,若是您已掌握下面知識事項,則可跳過此環節直接進入題目練習javascript
若是您對某些部分有些遺忘,👇🏻 已經爲您準備好了!前端
Generator 的學習java
Generator
函數是ES6
中提供的一種 異步編程解決方案。語法上,首先能夠把它理解成,Generator
函數是一個 狀態機,封裝了多個內部狀態,須要使用 next()函數來繼續執行下面的代碼。
function* helloWorldGenerator() { yield 'hello' yield 'world' return 'ending' } var hw = helloWorldGenerator() hw.next() // { value: 'hello', done: false } hw.next() // { value: 'world', done: false } hw.next() // { value: 'ending', done: true } hw.next() // { value: undefined, done: true }
next()
方法返回一個包含屬性done
和value
的對象。該方法也能夠經過接受一個參數用以向生成器傳值
返回的對象包含兩個屬性:編程
done
(布爾類型)true
。 在這種狀況下,value
可選地指定迭代器的返回值。false
。 這至關於沒有徹底指定 done
屬性。value
- 迭代器返回的任意的 Javascript
值。當 done
的值爲 true
時能夠忽略該值。function* gen() { yield 1 yield 2 yield 3 } var g = gen() // "Generator { }" g.next() // "Object { value: 1, done: false }" g.next() // "Object { value: 2, done: false }" g.next() // "Object { value: 3, done: false }" g.next() // "Object { value: undefined, done: true }"
return()
方法返回給定的值並結束生成器
function* gen() { yield 1 yield 2 yield 3 } var g = gen() g.next() // { value: 1, done: false } g.return('foo') // { value: "foo", done: true } g.next() // { value: undefined, done: true }
throw()
方法用來向生成器拋出異常,並恢復生成器的執行,返回帶有done
及value
兩個屬性的對象
done
(布爾類型)true
。在這種狀況下,能夠指定迭代器 value
的返回值。false
。 這至關於不指定 done
屬性的值。value
- 迭代器返回的任何 JavaScript
值。當 done
是 true
的時候能夠省略。function* gen() { while (true) { try { yield 42 } catch (e) { console.log('Error caught!') } } } var g = gen() g.next() // { value: 42, done: false } g.throw(new Error('Something went wrong')) // "Error caught!"
var readFile = function (name, ms) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(name + '讀完了') resolve() }, ms) }) } var gen = function* () { console.log('指定generator') yield readFile('first', 1000) yield readFile('second', 2000) return '完成了' } var g = gen() var result = g.next() result.value .then(() => { g.next() }) .then(() => { g.next() })
優勢:數組
co
函數庫使用缺點:微信
更多知識請點擊JavaScript 異步發展史異步
一:Generator 函數的 yield 關鍵字的做用是()?async
二:以下代碼執行後打印結果爲()異步編程
function* generator(i) { yield i yield i * 2 } const gen = generator(10) console.log(gen.next().value) console.log(gen.next().value)
[0, 10]
, [10, 20]
20
, 20
10
, 20
0, 10
and 10, 20
三:以下代碼執行後打印結果爲()
function* generatorOne() { yield ['a', 'b', 'c'] } function* generatorTwo() { yield* ['a', 'b', 'c'] } const one = generatorOne() const two = generatorTwo() console.log(one.next().value) console.log(two.next().value)
a
and a
a
and undefined
['a', 'b', 'c']
and a
a
and ['a', 'b', 'c']
1、
Answer:C
Generator
函數的調用方法與普通函數同樣,也是在函數名後面加上一對圓括號。不一樣的是,調用 Generator
函數後,該函數並不執行,返回的也不是函數運行結果,而是一個指向內部狀態的指針對象,也就是上一章介紹的遍歷器對象(Iterator Object
)。
下一步,必須調用遍歷器對象的 next
方法,使得指針移向下一個狀態。也就是說,每次調用 next
方法,內部指針就從函數頭部或上一次停下來的地方開始執行,直到遇到下一個 yield
表達式(或 return
語句)爲止。換言之,Generator
函數是分段執行的,yield
表達式是暫停執行的標記,而 next
方法能夠恢復執行。
2、
Answer:C
常規函數不能在調用後中途中止。可是,生成器函數能夠中途「中止」,而後從中止的地方繼續。每次生成器函數遇到yield
關鍵字時,該函數都會生成它後面指定的值。注意,在這種狀況下,生成器函數不返回值,而是生成值。
首先,咱們初始化生成函數,使 i 等於 10。咱們使用next()
方法調用生成器函數。第一次調用生成器函數時,i 等於 10。它遇到第一個 yield
關鍵字:它產生 i 的值。生成器如今是「暫停」的,10 被記錄。
而後,咱們使用next()
方法再次調用該函數。它開始在以前中止的地方繼續,仍然是 i 等於 10。如今,它遇到下一個yield
關鍵字,併產生 i*2
。i
等於 10
,因此它返回 10*2
,也就是 20
。結果是 10,20
。
3、
Answer:C
使用yield
關鍵字,咱們在生成器函數中產生值。 使用yield *
關鍵字,咱們能夠從另外一個生成器函數或可迭代對象(例如,數組)中產生值。 在generatorOne
中,咱們使用 yield
關鍵字產生整個數組['a','b','c']
。 一個對象的下一個方法(one.next()。value)
返回的對象的 value
屬性值等於整個數組['a','b','c']
。
console.log(one.next().value) // ['a', 'b', 'c'] console.log(one.next().value) // undefined
generatorTwo
中,咱們使用yield *
關鍵字。 這意味着咱們獲得的迭代器爲數組['a','b','c']
。 第一個產生的值爲數組中的第一個值 a,所以咱們第一次調用two.next().value
時,將返回 a
。後面繼續調用next()
則會持續返回b
和c
直到該數組調用結束。。
console.log(two.next().value) // 'a' console.log(two.next().value) // 'b' console.log(two.next().value) // 'c' console.log(two.next().value) // undefined