2.11. 生成器
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.
代码说明:
-
- 的位置没有限制
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield 语句后的值
- yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
- next 方法可以传递实参,作为 yield 语句的返回值
function* gen() {
yield '一只没有耳朵';
yield '一只没有尾巴';
return '真奇怪';
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
生成器函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生成器</title>
</head>
<body>
<script>
// 生成器其实就是一个特殊的函数
// 异步编程 纯回调函数 node fs ajax mongodb
// yield:函数代码的分隔符 【yield还有一个功能:返回yield后面的值】
// 【*可居左、中、右,尽量居左】
function* gen() {
// console.log(111);
yield '一只没有耳朵';
// console.log(222);
yield '一只没有尾部';
// console.log(333);
yield '真奇怪';
// console.log(444);
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// 遍历
// for(let v of gen()){
// console.log(v);
// }
</script>
</body>
</html>
生成器函数参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生成器函数参数</title>
</head>
<body>
<script>
function* gen(arg) {
console.log(arg); // AAA
let one = yield 111;
console.log(one); // BBB
let two = yield 222;
console.log(two); // CCC
let three = yield 333;
console.log(three); // DDD
}
// 执行获取迭代器对象
let iterator = gen('AAA');
console.log(iterator.next()); // {value: 111, done: false}
// next方法可以传入实参
console.log(iterator.next('BBB')); // {value: 222, done: false}
console.log(iterator.next('CCC')); // {value: 333, done: false}
console.log(iterator.next('DDD')); // {value: undefined, done: true}
</script>
</body>
</html>
生成器函数实例-1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生成器函数实例</title>
</head>
<body>
<script>
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作
// 1s 后控制台输出 111 2s后输出 222 3s后输出 333
// 回调地狱
// setTimeout(() => {
// console.log(111);
// setTimeout(() => {
// console.log(222);
// setTimeout(() => {
// console.log(333);
// }, 3000);
// }, 2000);
// }, 1000);
function one() {
setTimeout(() => {
console.log(111);
iterator.next();
}, 1000)
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next();
}, 2000)
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next();
}, 3000)
}
function* gen() {
yield one();
yield two();
yield three();
}
// 调用生成器函数
let iterator = gen();
iterator.next();
// 如果要连续3次调用next,达到同样的效果,则后面2个定时器的时间需要写成3000、6000,表示距离第一次调用的时间为2s、5s
// itr.next()
// itr.next()
// itr.next()
</script>
</body>
</html>
生成器函数实例-2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生成器函数</title>
</head>
<body>
<script>
// 模拟获取 用户数据 订单数据 商品数据
function getUsers() {
setTimeout(() => {
let data = '用户数据';
// 调用 next 方法, 并且将数据传入
iterator.next(data);
}, 1000);
}
function getOrders() {
setTimeout(() => {
let data = '订单数据';
iterator.next(data);
}, 1000)
}
function getGoods() {
setTimeout(() => {
let data = '商品数据';
iterator.next(data);
}, 1000)
}
function* gen() {
let users = yield getUsers();
let orders = yield getOrders();
let goods = yield getGoods();
}
// 调用生成器函数
let iterator = gen();
iterator.next();
</script>
</body>
</html>