JavaScript-生成器
生成器其实就是一个特殊的函数
异步编程:纯回调函数 node fs ajax mongodb
function * gen(){
console.log("hello generator")
}
let iterator = gen();
iterator.next();
<!------------------------------------------>
function * gen(){
console.log(111)
yield 'hhh'
console.log(222)
yield 'sss'
console.log(333)
yield 'aaa'
console.log(444)
}
let iterator = gen();
iterator.next(); // 111
iterator.next(); // 222
iterator.next(); // 333
iterator.next(); // 444
// 通过next方法来控制代码向下执行
console.log(iterator.next()) // {value:'hhh',done:false}
console.log(iterator.next()) // {value:'sss',done:false}
console.log(iterator.next()) // {value:'aaa',done:false}
console.log(iterator.next()) // {value:undefined,done:true}
// 此处是迭代器对象,因此还可以用for..of进行遍历
for(let v of gen()){
console.log(v) // hhh // sss // aaa
// 返回结果是yield后面的表达式
}
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
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
# 生成器函数参数
function * gen(arg){
console.log(arg) // AAA
let one = yield 111;
console.log(one) // BBB
let two = yield 222;
console.log(two)
let three = yield 333;
console.log(three)
}
// 执行获取迭代器对象
let iterator = gen('AAA')
console.log(iterator.next())
// next方法可以传入实参
// 第二次调用next方法传入实参,将作为第一个yield语句返回结果
console.log(iterator.next('BBB'))
// 第三次调用next方法传入实参,将作为第二个yield语句返回结果
console.log(iterator.next('CCC'))
// 第四次调用next方法传入实参,将作为第三个yield语句返回结果
console.log(iterator.next('DDD'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 生成器函数实例
异步编程 文件操作 网络操作 数据库操作
需求: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()
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
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
需求:模拟获取 用户数据 订单数据 商品数据
function getUsers(){
setTimeout(()=>{
let data = '用户数据'
// 这里是第二次调用next方法,作为第一个yield的返回值
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()
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
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
上次更新: 2024/08/14, 04:14:33