es6新增-Generator(异步编程的解决方案2)

目录

Generator生成器函数

一.使用和注意事项

1.定义(yield关键字只能出现在生成器函数中)

2.调用

3.遍历

二.next()方法传参(好难*)

三.yield*表达式

1.yield*表达式的使用

四.应用


Generator生成器函数

一.使用和注意事项

1.定义(yield关键字只能出现在生成器函数中)

function* g(){

*:生成器函数的标识,在function关键字和函数名之间就可

yield “钱”

yield “多”

yield “多”

}

形式上,Generator函数是一个普通函数,但是有两个特征

a.function关键字与函数名之间有一个星号*

b.函数体内部使用yiled表达式,定义不同的内部状态(yiled的意思是“产出”)

2.调用

生成器函数调用,不会立即执行函数体,

而是返回一个Iterator遍历器对象调用next()方法则继续往后执行碰到yield关键字就暂停

const genObj = g()

console.log(genObj)

 console.log(genObj.next())

console.log(genObj.next())

console.log(genObj.next())

console.log(genObj.next())

3.遍历

for(let item of g()){

console.log(item)  }

输出:钱 多

只输出一个“多“的原因:(只限在Genterator函数中,在其他函数中正常遍历)

for item of循环碰到done为true的地方就结束了,只输出done为false的部分

二.next()方法传参(好难*)

function * g(a){

        const b = 2*(yield(a-1))

        const c = yield(b/4)

        return (a-b+c)

}

const o = g(2)

console.log(o.next()) //输出:{ value:1,done:false }

console.log(o.next(6))  //输出:{ value:3,done:false }

(yield(a-1)) = 6 则b = 12

console.log(o.next(3))  //输出:{ value:-7,done:true }

yield(b/4) = 3 则c = 3 先前赋值:a = 2,b = 12 则return = -7

const b = g(3)

console.log(b.next())  //输出:{ value:4,done:false }

console.log(b.next(0))  //输出:{ value:0,done:false }

(yield(a-1)) = 0 则b = 0

console.log(b.next(1)) //输出:{ value:4,done:true }

yield(b/4) = 1 则c = 1 先前赋值:a = 3,b = 0 则return = 4

三.yield*表达式

1.yield*表达式的使用

如果在Genderator函数内部,调用另一个Genderator函数。

需要在前面的Genderator的函数体内部,自己手动完成。

function * g1(){

        yield "冰";

        yield "墩";

        yield "墩";

}

function * g2(){

        yield "雪";

        //手动遍历 g1()

        for(let i of g1()){

                console.log(i)

        }

        yield "容";

        yield "融";

}

for(let v of g2()){

        console.log(v)

}

输出:雪 冰 墩 墩 容 融

上面代码中,g1和g2都是Genderator函数,在g2里面调用g1,就需要手动遍历g1()。

如果有多个Genderator函数嵌套,写起来就非常麻烦。

es6提供了 yield*表达式作为解决办法。

用来在一个Genderator函数里面执行另一个Genderator函数。

function *g2(){

        yiled "雪";

        yiled* g1()

        yield "容";

        yield "融";

}

示例

function * f1(){

        yiled "北京" 

}

function * f2(){

        yiled "hello" 

        yiled f1()

        yiled "东奥" 

}

const gen = f2()

console.log(gen.next().value) 输出:“hello”

console.log(gen.next().value) 输出:一个遍历器对象

console.log(gen.next().value) 输出:“东奥”

function * f3(){

        yiled "hello" 

        yiled* f1()

        yiled "东奥" 

}

const gen = f3()

console.log(gen.next().value) 输出:“hello”

console.log(gen.next().value) 输出:“北京”

console.log(gen.next().value) 输出:“东奥”

四.应用

生成器函数的应用:

React中Redux-Saga(dva)中间件,就是生成器函数的典型应用场景

需求:每隔1s按照顺序输出1,2,3,4,5

for(let i = 1;i<=5;i++){

        setTimeout(()=>{

                console.log(1)

        },1000)

}

输出:1s后同时输出1,2,3,4,5

改造:每隔1s按照顺序输出1,2,3,4,5

const delay = n =>new Promise(resolve =>{

        setTimeout(()=>{

                resolve(n)

        },1000)

})

function * g(){

        for(let i = 1;i<=5;i++){

                const x = yield delay(i)

                console.log(x)

        }

}

function co(g){

        const o = g()

        next()

        function next(a){

                const {value,done} = o.next(a)

                if(done) return

                value.then(data=>{

                        next(data)

                })

        }

}

co(g)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值