Amybiubiu / Blog

6 stars 0 forks source link

Babel 将 generator 编译成了什么(个人向笔记) #6

Open Amybiubiu opened 3 years ago

Amybiubiu commented 3 years ago

完整代码

function helloWorldGenerator() { // 1. wrap 之后返回一个 generator 具有原型上继承有 next 方法 return regeneratorRuntime.wrap( function helloWorldGenerator$(_context) { while (1) { switch ((_context.prev = _context.next)) { case 0: _context.next = 2; return "hello";

                case 2:
                    _context.next = 4;
                    return "world";

                case 4:
                    return _context.abrupt("return", "ending");

                case 5:
                case "end":
                    // 8. 最后一次直接执行 stop 没有参数传入,value 为 undefined
                    return _context.stop();
            }
        }
    },
    _marked,
    this
);

} // function* helloWorldGenerator() { // yield 'hello'; // yield 'world'; // return 'ending'; // } var hw = helloWorldGenerator();

console.log(hw.next()); console.log(hw.next()); console.log(hw.next()); console.log(hw.next());

调用的时候关键的是通过 wrap 函数返回一个 函数,进入 wrap 函数查看,
- wrap 函数
```js
   function wrap(innerFn, outerFn, self) {
        var generator = Object.create(outerFn.prototype);

        var context = {
            done: false,
            method: "next",
            next: 0,
            prev: 0,
            // 6. 'ending' 作为 arg 传入
            abrupt: function (type, arg) {
                var record = {};
                record.type = type;
                record.arg = arg;

                return this.complete(record);
            }, 
            complete: function (record, afterLoc) {
                if (record.type === "return") {
                    this.rval = this.arg = record.arg;
                    this.method = "return";
                    this.next = "end";
                }

                return ContinueSentinel;
            },
            stop: function () {
                this.done = true;
                // 7. 第三次的 next 最终返回值在此处,返回给 70 行 record arg
                return this.rval;
            }
        };

        generator._invoke = makeInvokeMethod(innerFn, context);

        return generator;
    }

wrap 函数返回了一个 generator 函数,该函数有继承自 outerFn 的 next 方法。这也是 next 能被执行的原因。

image

Amybiubiu commented 3 years ago