生成器
生成器函数时ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
function *gen() {
yield '一只没有眼睛'
yield '一只没有嘴巴'
yield '真奇怪'
}
let iterator = gen()
console.log(iterator.next()) // {value: "一只没有眼睛", done: false}
console.log(iterator.next()) // {value: "一只没有嘴巴", done: false}
console.log(iterator.next()) // {value: "真奇怪", done: false}
*
的位置没有限制- 生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句后的值
- yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next方法,执行上一个yield语句之后到yeild语句的代码(第一个yield语句执行函数开始到第一个yield的代码)
- next方法可以传递实参,作为上一条yield语句的返回值
function* gen(arg) {
console.log(arg)
let one = yield 111
console.log(one)
let two = yield 222
console.log(two)
let three = yield 333
console.log(three)
}
// 执行获取迭代器对象
let iterator = gen('GEN')
console.log(iterator.next())
// GEN
// {value: 111, done: false}
// next方法可以传参,传入参数将作为上一个yeild语句的返回结果
console.log(iterator.next('one'))
// one
// {value: 222, done: false}
console.log(iterator.next('two'))
// two
// {value: 333, done: false}
console.log(iterator.next('three'))
// three
// {value: undefined, done: true}
生成器的应用
模拟异步获取用户数据、订单信息和商品信息
function getUser() {
setTimeout(() => {
let data = '用户数据'
iterator.next(data)
}, 1000)
}
function getOrders() {
setTimeout(() => {
let data = '订单信息'
iterator.next(data)
}, 1000)
}
function getGoods() {
setTimeout(() => {
let data = '商品信息'
iterator.next(data)
}, 1000)
}
function* gen() {
const result = { user: undefined, orders: undefined, goods: undefined }
let user = yield getUser()
console.log(user) // 用户数据
result.user = user
let orders = yield getOrders()
console.log(orders) // 订单信息
result.orders = orders
let goods = yield getGoods()
console.log(goods) // 商品信息
result.goods = goods
console.log(result) // {user: "用户数据", orders: "订单信息", goods: "商品信息"}
}
let iterator = gen()
iterator.next()