1.Generator函数
Generator函数是ES6中提供的一种异步编程解决方法。Generator是一个状态机,可以依次遍历函数内部的没一个状态。简单可以理解为一个可暂停执行的函数,yield就是暂停标志。
- function后面有”*”
- 函数内部有yield表达式
1 2 3 4 5 6
| functon * call(){ console.log(1) yield '1' consol.log(2) yield '2' }
|
2.Generator函数执行机制
使用generator函数和使用普通函数一样,在后面加上()就可以了,但是函数并不会马上执行,而是返回一个指向内部函数的指针,调用遍历器对象Iterator的next方法,会分步执行generator函数中的对应逻辑
1 2 3 4 5 6 7 8 9
| let f = call f.next()
f.next()
f.next()
|
3.next方法
next函数不传入参数时yield表达式返回值是undefined,当next传入参数的时候参数会作为上一步yield的返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| functon * call2(){ console.log('开始') const a = yield 1 consol.log(a) const b = yield 2 console.log(b) }
const f2 = call2()
f2.next()
f2.next(10)
f2.next(20)
f2.next()
|
4.return方法
return返回给定值并结束遍历Generator函数。return有参数返回参数没参数返回undefined。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| functon * call3(){ console.log('开始') const a = yield 1 consol.log(a) const b = yield 2 console.log(b) }
const f3 = call3()
f3.next()
f3.next(10)
f3.return("end")
f3.next()
|
5.*yield
*yield表示yield返回另一个Generator对象,可以在Generator内部调用另一个Generator函数。
1 2 3 4 5 6 7 8 9 10 11 12
| function* callA() { console.log("callA: " + (yield)) } function* callerB() { while (true) { yield* callA(); } } const callerObj = callerB() callerObj.next() callerObj.next("first") callerObj.next("second")
|
6.async/await
ES7中引入,可以理解为Generator的语法糖,对Generator函数进行了修改。await等待的是一个隐式返回Promise作为结果的函数。async、await等同于一个generator+自动执行器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| function fn(nums) { return new Promise(resolve => { setTimeout(() => { resolve(nums * 2) }, 1000) }) } function* gen() { const num1 = yield fn(1) console.log(num1) const num2 = yield fn(num1) console.log(num2) const num3 = yield fn(num2) console.log(num3) return num3 } function generatorToAsync(generatorFn) { return function() { const gen = generatorFn.apply(this, arguments) return new Promise((resolve, reject) => { function go(key, arg) { let res try { res = gen[key](arg) } catch (error) { return reject(error) } const { value, done } = res if (done) { return resolve(value) } else { return Promise.resolve(value).then(val => go('next', val), err => go('throw', err)) } } go("next") }) } } const asyncFn = generatorToAsync(gen) asyncFn().then(res => console.log(res))
|