第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

TypeScript 生成器(Generator)

迭代器和生成器這兩個(gè)概念總是很容易混淆,經(jīng)過上節(jié)的學(xué)習(xí)我們知道迭代器是一個(gè)對象,那么本節(jié)首先要記?。?strong>生成器是一種能夠中途停止,然后從停止的地方繼續(xù)運(yùn)行的函數(shù)。可以借助 yieldreturn 停止函數(shù)運(yùn)行。

1. 慕課解釋

通過 function* 來創(chuàng)建一個(gè)生成器函數(shù),在調(diào)用一個(gè)生成器函數(shù)后,并不會立即執(zhí)行函數(shù)中的代碼,而是會返回一個(gè)迭代器對象,通過調(diào)用迭代器對象的 next() 方法,可以獲得 yield/return 的返回值。

2. 生成器函數(shù)的特殊性

一個(gè)正常的函數(shù),如果沒有 return 或者 throw 一個(gè)異常,一旦被調(diào)用在運(yùn)行結(jié)束之前是不會停止的。如果再次調(diào)用這個(gè)函數(shù),它會再次從第一行開始執(zhí)行。

function normalFunc() {
  console.log('I')
  console.log('cannot')
  console.log('be')
  console.log('stopped.')
}

In contrast, a generator is a function that can stop midway and then continue from where it stopped.

相反,生成器函數(shù)可以中途停止,然后從停止的地方繼續(xù)執(zhí)行的。

生成器函數(shù)會返回一個(gè)對象,可以調(diào)用這個(gè)對象上的 next() 方法。

3. 示例代碼

function* generatorFunction() { 
  console.log('開始執(zhí)行')
  yield 'Hello, '

  console.log('暫停后再次執(zhí)行')
  yield 'World!'
}

let iterator = generatorFunction()

此時(shí),通過 function* 語法創(chuàng)建了一個(gè)生成器函數(shù),調(diào)用這個(gè)函數(shù)并賦值給變量 iterator,我們已經(jīng)知道這是個(gè)對象。

console.log(iterator.next().value)
// 開始執(zhí)行
// Hello, 

調(diào)用 iterator 對象上的 next() 方法,首先打印出 開始執(zhí)行,然后遇到了 yield Hello,,yield 會將后面的值返回,生成器生成一個(gè)對象 { value: 'Hello, ', done: false },函數(shù)停止運(yùn)行,直到再次調(diào)用 next() 方法。

console.log(iterator.next().value)
// 暫停后再次執(zhí)行
// World!

再次調(diào)用 next() 方法,函數(shù)內(nèi)繼續(xù)執(zhí)行,打印出 暫停后再次執(zhí)行,遇到 yield 'World!',生成對象 { value: 'World!', done: false },函數(shù)停止運(yùn)行,直到再次調(diào)用 next() 方法。

console.log(iterator.next())

再次調(diào)用 next() 方法,這次函數(shù)內(nèi)沒有返回值,也就是默認(rèn)返回 undefined, 生成對象 { value: 'undefined', done: true }。

4. 通過 next() 參數(shù)向生成器傳值

在調(diào)用 next() 的時(shí)候可以傳遞一個(gè)參數(shù),在上次 yield 前接收到這個(gè)參數(shù):

function* gen() { 
  console.log('開始執(zhí)行')
  let res1 = yield 1
  console.log('中斷后繼續(xù)執(zhí)行')
  console.log(res1)
  
  let res2 = yield 2
  console.log(res2)
  
  console.log('執(zhí)行結(jié)束')
  return 3
}

let iterator = gen()
console.log(iterator.next('first'))
console.log(iterator.next('second'))
console.log(iterator.next('third'))

執(zhí)行并查看結(jié)果:

開始執(zhí)行
{ value: 1, done: false }
中斷后繼續(xù)執(zhí)行
second
{ value: 2, done: false }
third
執(zhí)行結(jié)束
{ value: 3, done: true }

這里注意下,生成器最初沒有產(chǎn)生任何結(jié)果,在第一次調(diào)用 next() 時(shí)傳參是無意義的。

5. 小結(jié)

生成器還有另一個(gè)巨大的好處,就是把異步回調(diào)代碼變成“同步”代碼。async await 就是基于生成器函數(shù)的語法糖,await 可以等待異步函數(shù)執(zhí)行完畢再繼續(xù)執(zhí)行后面的代碼。