很有意思的Generator function函数做参数的调用问题

知识点:

Generator function 生成函数的调用和启动不一样,调用之后,函数不没有启动,只有再调用gen.next()的时候,才进入函数体,函数才启动。

基本知识点回顾:

函数作为参数调用的时候,是在调用函数的时候,会先对参数求值,比如:

wrapper11(fn11())

上述代码如果是普通函数(非Generator function),那么一定是先执行完fn11()的,比如:

function startTest11() {
    function fn11() {
        console.log('startTest11 ==>> fn11 :: enter.')
        return 'fn11'
    }
    function  wrapper11(obj) {
        console.log('startTest11 ==>> wrapper11 :: enter.')
        return [obj]
    }
    const arr11 = [...wrapper11(fn11())]
    console.log('startTest11 ==>> wrapper :: arr11 = ', arr11)
}
startTest11()
// 输出如下:
// startTest11 ==>> fn11 :: enter.
// startTest11 ==>> wrapper11 :: enter.
// startTest11 ==>> wrapper :: arr11 =  [ 'fn11' ]

疑问产生:

但是,如果是生产函数,貌似不太一样,注意啊,是貌似

function startTest10() {
    function * fn10() {
        console.log('startTest10 ==>> fn10 :: enter.');
        yield 1;
        yield 2;
        return 'fn10';
    }
    function * wrapper10(genObj) {
        console.log('startTest10 ==>> wrapper10 :: enter.');
        yield 'a';
        yield 'b';
        const rst  = yield* genObj
        console.log('startTest10 ==>> wrapper10 :: rst = ', rst);
    }
    // wrapper(fn())
    const arr10 = [...wrapper10(fn10())];
    console.log('startTest10 ==>> end :: arr10 = ', arr10);
}

// 输出如下:
// startTest10 ==>> wrapper10 :: enter.
// startTest10 ==>> fn10 :: enter.
// startTest10 ==>> wrapper10 :: rst =  fn10
// startTest10 ==>> end :: arr10 =  [ 'a', 'b', 1, 2 ]

注意看,在调用const arr10 = [...wrapper10(fn10())];,从日志看,貌似是违背了理解的常规的函数调用逻辑,没有先输出startTest10 ==>> fn10 :: enter.,反而是先输出startTest10 ==>> wrapper10 :: enter.,感觉有些不可思议。

其实,我理解的不是这样的,还是先调用了fn10(),只是fn10是一个生成函数,生成函数需要在调用其返回值时一个迭代器,genObj.next()才启动。因此,刚掉完fn10()的时候,函数并没有内容输出。 [...wrapper10(fn10())]会自动遍历wrapper10结果的迭代器,此时完成第一层的遍历。

第二层遍历是wrapper10函数体中的yield*,const rst  = yield* genObj,这个类似一个for of 循环:

// 参数genObj是一个迭代器
function* gen(genObj) {
    yield* genObj
}

相当于

// 参数genObj是一个迭代器
function* gen(genObj) {
    for(const item of genObj) {
        yield item
    }
}

此时才启动进入fn10的函数的返回值,因此看上去像是函数参数方法调用晚了。其实不是,只是因为启动晚了而已。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值