前言
- 书写
和定义普通的函数差不多,只是在function后面添加*
var normal = function () {} // 普通函数
var gen = function* () {} //Generator函数
- 返回
调用这个生成器返回的是一个对象,该函数有两个属性值
- 一个是返回的value值
value依据定义返回相应的值 - 另外一个是一个布尔值,表示是否迭代完毕,或造作完成
用done来表示
- 优点
- 像打断点一样
- 解决异步问题,不在需要回调
- 例子
// 疯狂回调
request(url, function (err, res, body) {
if (err) handleError(err)
fs.writeFile('x.txt', body, function (err) {
if (err) handleError(err)
request(url2, function (err, res, body) {
if(err) handleError(err)
})
})
})
// Promise使用
request(url)
.then(function (result) {
return fs.writeFile('x.txt', result)
})
.then(function (result) {
return request(url2)
})
.catch(function (e) {
handleError(e)
})
// Generator 生成器
var result = yield request(url)
yield writeFileAsync('x.txt', result)
yield request(url2)
使用
- yield
let foo1 = function* () {
yield 0
yield 1
return 2
yield 3
}
let fn1 = foo1()
fn1.next() // {value: 0, done: false}
fn1.next() // {value: 1, done: false}
fn1.next() // {value: 2, done: true}
fn1.next() // {value: undefined, done: true}
return后的yield失效
- yield*
可以实现在generator函数中使用其他的generator函数
let foo1 = function* () {
yield 1
yield 2
}
let foo2 = function* () {
yield 0
yield* foo1()
yield 3
}
let fn1 = foo2()
fn1.next() // {value: 0, done: false}
fn1.next() // {value: 1, done: false} foo1中的
fn1.next() // {value: 2, done: false} foo1中的
fn1.next() // {value: 3, done: false}
fn1.next() // {value: undefined, done: true}
- next()方法的参数
next带参数,则将该参数作为上一次yield返回的值
let foo3 = function*(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 4)
return x + y + z
}
let fn1 = foo3(2)
let fn2 = foo3(3)
fn1.next() // {value: 3,done:false} 有参数2
fn1.next() // {value:NaN, done:false} 无参数,则无返回值,所以计算得NaN
fn2.next() // {value: 4,done:false} 有参数3, x=3
fn2.next(8) // {value: 4,done: false} 有参数8,则8*2/4 等于4,此时y=16
fn2.next(9) // {value: 28,done: true} 有参数9,所以z=9,return 3+16+9 = 28
- return方法
这里的return不是说函数里面定义的return,而是generator函数的return方法
let foo4 = function*() {
yield 0
yield 1
yield 2
}
let fn = foo4()
fn.next() // { value: 0, done: false }
fn.return('提前结束啦') // { value: '提前结束啦', done: true } done已经转化成true啦
实际应用
node中的express,koa