在这里,本文都是通过定时来模拟ajax请求.
定义
看一下mnd怎么说的?
生成器函数提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。 生成器函数使用 function*语法编写。 最初调用时,生成器函数不执行任何代码,而是返回一种称为Generator的迭代器。 通过调用生成器的下一个方法消耗值时,Generator函数将执行,直到遇到yield关键字。
怎样写一个生成器呢?
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
for (let i = start; i < end; i += step) {
yield i;
}
}
又是如何调用的呢?
var a = makeRangeIterator(1, 10, 2)
console.log(a.next()) // {value: 1, done: false}
console.log(a.next()) // {value: 3, done: false}
console.log(a.next()) // {value: 5, done: false}
console.log(a.next()) // {value: 7, done: false}
console.log(a.next()) // {value: 9, done: false}
console.log(a.next()) // {value: undefined, done: true}
它和我们迭代器都差不多,都有一个next方法,每次调用,就只是执行一段代码。返回的也是value和done。
使用场景
先来一个简单的例子:
需求:1秒后,打印111,2秒后打印222,3秒后打印333
原生写法:
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 1000)
}, 1000)
}, 1000)
这就是我们常说的回调地狱问题了。
使用yiled函数实现
function one() {
setTimeout(() => {
console.log(111);
b.next()
}, 1000);
}
function two() {
setTimeout(() => {
console.log(222);
b.next()
}, 1000);
}
function three() {
setTimeout(() => {
console.log(333);
b.next()
}, 1000);
}
function* gen() {
yield one()
yield two()
yield three()
}
let b = gen()
b.next()
这样一来我们就能解决回调地狱的问题了。
案例2:
需求:要先拿到用户数据,再通过用户数据去查询订单,最后查询商品
在这里,我们也是用定时器模拟数据获取,并传值的过程
function getUserData() {
setTimeout(() => {
let data = '用户数据'
iterator.next(data)
}, 1000);
}
function getOrderData(datas) {
setTimeout(() => {
let data = '订单数据'
console.log(datas, 'datas');
iterator.next(data)
}, 1000);
}
function getShopData() {
setTimeout(() => {
let data = '商品数据'
iterator.next(data)
}, 1000);
}
function* getData() {
let users = yield getUserData()
console.log(users);
let orders = yield getOrderData(users)
console.log(orders);
let shops = yield getShopData()
console.log(shops);
}
let iterator = getData()
iterator.next()
通过这样的方式,我们代码的缩进有头,且不会产生回调地狱问题。
更多知识推荐:
MDN:迭代器和生成器
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Iterators_and_Generators
IBM:详解 ECMAScript 6 中的生成器(Generator)https://developer.ibm.com/zh/languages/javascript/articles/wa-es6-generator