`

regenerator-runtime

阅读更多

regenerator-runtime模块来自facebook的regenerator模块。

生成器函数、async、await函数经babel编译后,regenerator-runtime模块用于提供功能实现。

 

// version="0.10.3"

!(function(global) {
  "use strict";

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  // module存在,runtime添加为module.exports的属性,或者作为module.exports的值,用于模块化加载并导出
  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      module.exports = runtime;
    }
    return;
  }

  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  // prototype属性为迭代器的原型,prototype.constructor属性为GeneratorFunctionPrototype构造函数
  function Generator() {}
  // prototype属性为GeneratorFunctionPrototype构造函数
  // displayName属性为"GeneratorFunction"
  function GeneratorFunction() {}
  // prototype属性为迭代器的原型,prototype.constructor属性为GeneratorFunctionPrototype构造函数
  // constructor属性为GeneratorFunction构造函数
  // [toStringTagSymbol]属性为"GeneratorFunction"
  function GeneratorFunctionPrototype() {}

  // 迭代器原型prototype属性
  var IteratorPrototype = {};
  IteratorPrototype[iteratorSymbol] = function () {
    return this;
  };

  var getProto = Object.getPrototypeOf;
  // NativeIteratorPrototype赋值为原生迭代器的原型prototype属性
  // values函数将iterable封装成可调用next方法进行迭代取值的迭代器
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && // Object.prototype
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction";

  // Gp除是迭代器原型外,为其添加next、throw、return方法,方法内部调用_invoke方法
  // _invoke方法须调用runtime.wrap方法才赋予Gp实例
  defineIteratorMethods(Gp);

  Gp[toStringTagSymbol] = "Generator";

  Gp.toString = function() {
    return "[object Generator]";
  };

  // defineIteratorMethods(prototype)函数为prototype添加next、throw、return方法,方法内部调用_invoke方法
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  // 判断是否生成器函数
  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  // 为编译后的生成器函数提供功能支持
  // 编译前
  // function* a() {
  //   yield 1;
  // }
  //
  // 编译后
  // var _marked = [a].map(regeneratorRuntime.mark);
  //
  // function a() {
  //   return regeneratorRuntime.wrap(function a$(_context) {
  //     while (1) {
  //       switch (_context.prev = _context.next) {
  //         case 0:
  //           _context.next = 2;
  //           return 1;
  //         case 2:
  //         case "end":
  //           return _context.stop();
  //       }
  //     }
  //   }, _marked[0], this);
  // }

  // 获取迭代器原型对象generator(该对象设定了next、throw、return方法),添加_invoke方法后返回
  // 因_invoke方法的添加,next方法执行时将调用innerFn特定条件分支,throw方法报错,return执行完成
  function wrap(innerFn, outerFn, self, tryLocsList) {
    // 用户设定的outerFn通过runtime.mark方法封装后,outerFn.prototype instanceof Generator返回真值
    //    此时outerFn.prototype为迭代器的原型对象Object.create(IteratorPrototype)
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);// 迭代器的原型对象
    var context = new Context(tryLocsList || []);

    // makeInvokeMethod(innerFn,self,context)函数
    // 参数innerFn待控制执行的函数,self为innerFn执行时的上下文,context为控制innerFn条件分支执行状态的操纵对象
    // 返回invoke函数,触发innerFn函数以特定的条件分支执行,或报错,或终结生成函数
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // 执行fn函数,以obj为上下文,arg为参数,返回{type:"normal",arg:fn.call(obj,arg)}或{type:"throw",arg:err}
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  // 将传参genFun函数封装成生成器函数"GeneratorFunction",具体细节是
  //    __proto__属性设置为GeneratorFunctionPrototype,[toStringTagSymbol]属性设为"GeneratorFunction"
  //    prototype属性设为Gp对象(迭代器原型),即Generator的prototype的原型,使genFun instanceof Generator返回真值
  // 注:instanceof方法用于判断对象是否某构造函数的实例,就其本质通过判断该对象是否由构造函数的原型对象Object.create创建
  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      if (!(toStringTagSymbol in genFun)) {
        genFun[toStringTagSymbol] = "GeneratorFunction";
      }
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };



  // 为编译后的async、await函数提供功能支持
  // 编译前
  // var asyncReadFile = async function () {
  //   var f1 = await readFile('/etc/fstab');
  //   var f2 = await readFile('/etc/shells');
  //   console.log(f1.toString());
  //   console.log(f2.toString());
  // };
  // 编译后???

  // `await x`编译成成`yield regeneratorRuntime.awrap(x)`, x添加__await属性为arg
  // async函数中的yield编译后,由AsyncIterator使其返回promise对象
  runtime.awrap = function(arg) {
    return { __await: arg };
  };

  // 通过_invoke方法使AsyncIterator.next|return|throw方法返回promise对象,实现异步逻辑
  // 当存在await函数时,将延迟函数的返回值value作为下一次next方法的参数
  // 当不存在await函数时,将延迟对象的返回值以{value:value}输出给成功或失败的回调函数
  function AsyncIterator(generator) {
    function invoke(method, arg, resolve, reject) {
      // try(fn,obj,arg)执行fn函数,以obj为上下文,arg为参数
      // 返回{type:"normal",arg:fn.call(obj,arg)}或{type:"throw",arg:err},err为fn执行过程中捕获的错误
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        // await函数包裹,再次调用invoke函数装饰将延迟函数返回值value传递给另一个Promise对象
        // 成功或失败时的回调函数是promise延迟对象
        if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
          return Promise.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        // 没有await函数包裹,resolve函数获得的参数为{value},返回值的value属性为延迟函数的返回值
        // 成功或失败时的回调函数是普通函数,不是promise对象
        return Promise.resolve(value).then(function(unwrapped) {
          result.value = unwrapped;
          resolve(result);
        }, reject);
      }
    }

    if (typeof process === "object" && process.domain) {
      invoke = process.domain.bind(invoke);
    }

    // 再次调用AsyncIterator的next、throw、return方法时,previousPromise为真值
    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new Promise(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise = previousPromise 
        // 首次调用AsyncIterator的next方法,callInvokeWithMethodAndArg构造promise对象作为成功或失败的回调
        ? previousPromise.then( callInvokeWithMethodAndArg, callInvokeWithMethodAndArg )
        // 首次调用AsyncIterator的next方法,返回promise,并赋值给previousPromise
        : callInvokeWithMethodAndArg();
    }

    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  runtime.AsyncIterator = AsyncIterator;

  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator( wrap(innerFn, outerFn, self, tryLocsList) );

    return runtime.isGeneratorFunction(outerFn) ? iter 
      : iter.next().then(function(result) { return result.done ? result.value : iter.next(); });
  };



  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  var ContinueSentinel = {};

  // 参数innerFn待控制执行的函数,self为innerFn执行时的上下文,context为控制innerFn条件分支执行状态的操纵对象
  // 返回invoke函数,触发innerFn函数以特定的条件分支执行,或报错,或终结生成函数
  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    // 若method为"throw",报错
    // 若method为"return",context.next赋值为"end",执行innerFn中"end"条件语句分支
    // 若method为"next",迭代context.delegate.interator,修改context.next,以执行innerFn中特定条件语句分支
    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      // 生成器函数执行完成,报错或者返回{value:undefined,done:true}
      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        return doneResult();
      }

      context.method = method;
      context.arg = arg;

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          // 迭代context.delegate.iterator,顺利迭代时delegateResult赋值为迭代值{value,done}
          // 报错或迭代完成时,delegateResult赋值为ContinueSentinel,并修改引用对象context的内部属性
          //    同时context.delegate赋值为null,以退出while循环
          var delegateResult = maybeInvokeDelegate(delegate, context);
          // 迭代context.delegate.iterator过程中报错或迭代完成,进入下一条循环语句
          //    同时因context.delegate=null,直接进入针对context.method作处理的条件语句部分
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }

        if (context.method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = context.arg;

        } else if (context.method === "throw") {
          // 若context.delegate.iterator初始迭代过程即报错,或method参数为"throw",未执行innerFn函数
          //    state状态更迭为GenStateCompleted,同时直接抛出错误
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw context.arg;
          }

          // 将异常存储在this.tryEntries,并调整context.next的值,进而决定innerFn执行哪个条件语句
          context.dispatchException(context.arg);

        } else if (context.method === "return") {
          // 根据context.prev筛选this.tryEntries,以变更context.next,使innerFn执行特定finally条件分支
          // 执行完成后context.method仍旧为return,再次调用makeInvokeMethod函数使生成器函数终结
          context.abrupt("return", context.arg);
        }

        state = GenStateExecuting;

        // try(fn,obj,arg)执行fn函数,以obj为上下文,arg为参数
        // 返回{type:"normal",arg:fn.call(obj,arg)}或{type:"throw",arg:err},err为fn执行过程中捕获的错误
        // innerFn函数中使用执行寻常语句调用或捕获错误等,由context.next决定执行innerFn的哪个条件语句
        //    switch(context.prev=context.next){
        //        case context.tryEntries[tryLoc]:
        //          ...
        //        case context.tryEntries[catchLoc}]:
        //          ...
        //        case context.tryEntries[finallyLoc}]:
        //          ...
        //        case context.tryEntries[afterLoc}]:
        //        case 'end':
        //          ...
        //          context.stop();
        //    }
        var record = tryCatch(innerFn, self, context);

        if (record.type === "normal") {
          // context.done为真,生成器函数执行完成;为否,生成器函数仍有yield语句需要执行
          state = context.done ? GenStateCompleted : GenStateSuspendedYield;

          if (record.arg === ContinueSentinel) {
            continue;
          }

          // 生成器函数返回值,单条yield语句或执行完成时的返回值
          return {
            value: record.arg,
            done: context.done
          };

        // 重新进入循环语句,调用context.dispatchException处理错误
        } else if (record.type === "throw") {
          state = GenStateCompleted;
          context.method = "throw";
          context.arg = record.arg;
        }
      }
    };
  }

  // 尝试迭代context.delegate.iterator迭代器中各函数,顺利迭代,返回迭代值{value,done}
  //    迭代完成时,为context[delegate.resultName]赋值为最终的迭代值value,context.delegate赋值为null
  //        并返回ContinueSentinel,供makeInvokeMethod捕获处理
  //    迭代有错时,context.method赋值为"throw",context.arg赋值为错误,context.delegate赋值为null
  //        并返回ContinueSentinel,供makeInvokeMethod捕获处理
  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];
    if (method === undefined) {
      // context.method为"throw"或"return"时,context.delegate置为null,以退出makeInvokeMethod中while循环
      context.delegate = null;

      if (context.method === "throw") {
        // return=delegate.iterator.return方法存在时,尝试调用maybeInvokeDelegate函数,以执行return方法
        if (delegate.iterator.return) {
          context.method = "return";
          context.arg = undefined;
          maybeInvokeDelegate(delegate, context);

          if (context.method === "throw") {
            return ContinueSentinel;
          }
        }

        context.method = "throw";
        context.arg = new TypeError("The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    // try(fn,obj,arg)执行fn函数,以obj为上下文,arg为参数
    // 返回{type:"normal",arg:fn.call(obj,arg)}或{type:"throw",arg:err},err为fn执行过程中捕获的错误
    var record = tryCatch(method, delegate.iterator, context.arg);

    if (record.type === "throw") {
      context.method = "throw";
      context.arg = record.arg;
      context.delegate = null;
      return ContinueSentinel;
    }

    var info = record.arg;

    if (!info) {
      context.method = "throw";
      context.arg = new TypeError("iterator result is not an object");
      context.delegate = null;
      return ContinueSentinel;
    }

    // context.delegate.iterator迭代完成,context[delegate.resultName]赋值为迭代返回值
    //    context.next赋值为delegate.nextLoc,context.method按条件赋值为"next",
    if (info.done) {
      context[delegate.resultName] = info.value;

      context.next = delegate.nextLoc;

      if (context.method !== "return") {
        context.method = "next";
        context.arg = undefined;
      }
    } else {
      return info;
    }

    context.delegate = null;
    return ContinueSentinel;
  }



  // 遍历取出object对象的集合,使用next方法迭代形式取出反序排列的该属性名集合
  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      next.done = true;
      return next;
    };
  };

  // 参数iterable传入迭代器或数组,封装成可调用next方法进行迭代取值的迭代器
  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    return { next: doneResult };
  }
  runtime.values = values;



  // 生成器函数或迭代器执行完成,返回{ value: undefined, done: true }
  function doneResult() {
    return { value: undefined, done: true };
  }



  // pushTryEntry([tryLoc,catchLoc,finallyLoc,afterLoc]),tryLoc,catchLoc,finallyLoc,afterLoc均为数值型
  // this.tryEntries添加{tryLoc,catchLoc,finallyLoc,afterLoc}
  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  // 重置this.tryEntries[i].completion属性
  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // this.tryEntries初始化赋值
    this.tryEntries = [{ tryLoc: "root" }];

    // 为this.tryEntries添加{tryLoc,catchLoc,finallyLoc,afterLoc}元素
    tryLocsList.forEach(pushTryEntry, this);

    // 初始化各实例属性,同时this.tryEntries数组中各项添加completion={type:"normal"}属性
    this.reset(true);
  }

  // 操控context.next变更,以制约innerFn执行时会进入哪个条件语句分支
  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      // context.prev在innerFn函数内变更为context.next,用于决定dispatchException实例方法该怎样调整context.next
      // context.next在实例方法dispatchException中改变,用于决定innerFn执行哪个条件分支语句
      //    或者在maybeInvokeDelegate函数赋值为context.delegate.nextLoc
      // innerFn函数中使用执行寻常语句调用或捕获错误等,由context.next决定执行innerFn的哪个条件语句
      //    switch(context.prev=context.next){
      //        case context.tryEntries[tryLoc]:
      //          ...
      //        case context.tryEntries[catchLoc}]:
      //          ...
      //        case context.tryEntries[finallyLoc}]:
      //          ...
      //        case context.tryEntries[afterLoc}]:
      //        case 'end':
      //          ...
      //          context.stop();
      //    }
      this.prev = 0;
      this.next = 0;

      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined;

      // this.done由context实例的stop方法赋值为true,表示迭代终止???
      this.done = false;

      // this.deletate={iterator,resultName,nextLoc}
      this.delegate = null;

      // this.method="next"|"return" |"throw" 通过执行实例方法或直接赋值改变
      //    当值为"next"时,maybeInvokeDelegate函数对this.delegate.iterator迭代取值
      //    当值为"throw"时(该更改过程只能通过在外部对context.method作赋值更改)
      this.method = "next";
      this.arg = undefined;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    // 抛出this.tryEntries[0]中存储的错误对象;this.done赋值为true,意味生成器函数执行完成
    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    // 将exception存储到this.tryEntries数组项{tryLoc,catchLoc,finallyLoc,completion:{type:"throw",arg:exception}}中,
    // 条件是context.prev的值大于this.tryEntries数组项的tryLoc属性,小于catchLoc或finallyLoc
    // 若context.prev小于各tryLoc,通过this.tryEntries[0]将context.next赋值为"end",进入innerFn函数的end条件语句
    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;

        if (caught) {
          context.method = "next";
          context.arg = undefined;
        }

        return !! caught;
      }

      // 反向遍历this.tryEntries,判断用户配置的tryLoc、catchLoc、finallyLoc后进行操作
      // 当context.prev>=tryLoc时,获取同数组项this.tryEntries[i]的catchLoc、finallyLoc,赋值给context.next
      //      同时将捕获的错误exception赋值给this.tryEntries[i]的completion属性,即{type:"throw",arg:exception}
      //      若进入catchLoc条件分支,意为忽略错误,context.method赋值为"next",context.arg赋值为undefined
      // 若没有catchLoc、finallyLoc,遍历到this.tryEntries[i-1],最终遍历到this.tryEntries[0]={tryLoc:"root"}
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    // context.next根据context.prev赋值为this.tryEntries中相关的finallyLoc,以执行innerFn中finally条件分支
    // 或者调用complete实例方法改变context.next,报错或执行innerFn中的特定条件分支
    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && 
          this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry && (type === "break" || type === "continue") &&
          finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.method = "next";
        this.next = finallyEntry.finallyLoc;
        return ContinueSentinel;
      }

      return this.complete(record);
    },

    // 报错或修改context.next值,以调用innerFn中的特定条件分支;或终结生成器函数
    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = this.arg = record.arg;
        this.method = "return";
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }

      return ContinueSentinel;
    },

    // 调用complete实例方法,传参为this.tryEntries[i](其finallyLoc属性与finallyLoc相符)的completion、afterLoc属性
    // 最终重置context实例的this.tryEntries[i].completion属性
    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    // 捕获this.tryEntries[i](其finallyLoc属性与tryLoc相符)中存储的错误对象,并返回
    // 若this.tryEntries中没有与tryLoc相符的数组项,报错
    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      throw new Error("illegal catch attempt");
    },

   
    // context.delegateYield被调用时,context.delegate.iterator迭代器将代替innerFn输出内容
    //    即先执行context.delegate.iterator,返回真值直接输出;否值调用innerFn输出结果
    //    context.delegate.iterator生成器中,通过指定nextLoc跳回到innerFn中
    // 设置context.delegate.iterator迭代器,该迭代器在maybeInvokeDelegate函数中调用
    //    迭代完成为context[context.delegate.resultName]赋值为最终迭代值value,context.next为nextLoc
    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),// values函数将iterable封装成可调用next方法进行迭代取值的迭代器
        resultName: resultName,// this.delegate.iterator迭代完成返回value时,为context[resultName]=value
        nextLoc: nextLoc
      };

      if (this.method === "next") {
        this.arg = undefined;
      }

      return ContinueSentinel;
    }
  };
})(
  typeof global === "object" ? global :
  typeof window === "object" ? window :
  typeof self === "object" ? self : this
);

 

0
0
分享到:
评论

相关推荐

    前端开源库-regenerator-runtime-only

    前端开源库-regenerator-runtime-only仅限于再生器运行时,仅限于再生器的运行时部分

    regenerator-runtime.7z

    微信小程序中使用Async-await方法异步请求变为同步请求所需的依赖工具类;微信小程序中使用Async-await方法异步请求变为同步请求所需的依赖工具类;

    regenerator-runtime.zip

    异步加载包,你可以直接点击链接在git上下载也可以直接下载这个文件,下载后解压到util目录下就可以了

    CyberChef_v9.46.0

    CyberChef是英国情报机构政府通信总部(GCHQ)发布了一款新型的开源Web工具,为安全从业人员分析和解密数据提供了方便。CyberChef 是一个简单、直观的 Web 应用程序,用于在 Web 浏览器中执行各种“网络”操作。...

    nuxt应用

    please import regenerator-runtime/runtime instead. 解决方法:npm install --save-dev babel-polyfill 构建设置 # install dependencies $ npm install # serve with hot reload at localhost:3000 $ npm run ...

    前端开发框架 React 离线 js 类库 (react @16.8.0)

    包含如下四个文件: - react.development.js,react核心库; - react-dom.development.js,支持react操作DOM; - babel.min.js,用于将jsx转为js; - prop-types.js,用户检查组件的 Props。

    eleventy-plugin-react:一个允许您将React用作Eleventy模板语言的插件

    安装npm install eleventy-plugin-react @babel/core @babel/preset-env @babel/preset-react react react-dom core-js@3 regenerator-runtime 或者yarn add eleventy-plugin-react @babel/core @babel/preset-env @...

    runtime.js

    微信小程序开发过程中本地设置勾选了“ES6转ES5"和"增强编译"两个选项,即使未引用regenerator-runtime,可以在开发工具里正常写async await,真机调试也OK。但在低版本微信可能无法支持async和await,建议下载...

    小程序如何支持使用 async/await详解

    前言 小程序本身是不支持async/await语法的,但有些应用场景,我们使用async/await会使得代码更简洁,也更易于维护,用过都知道是有多爽的。...2. 安装 regenerator-runtime,命令行执行 npm i regenerator-

    webpackUse:使用Webpack创建Web时的使用示例

    loader自动前缀npm install --save-dev文件加载器npm install --save-dev babel-loader @ babel /核心@ babel /预设环境npm install --save-dev core-js @ 3 regenerator-runtime npm install --save-dev eslint ...

    algorithm:算法练习

    安装npm install jest -- save - devnpm install babel - jest @ babel / core @ babel / preset - env regenerator - runtime - D编辑package.json { " scripts " : { " test " : " jest " }}编辑.babelrc { " ...

    JavaScript-leetcode-learn:JavaScript算法与数据结构学习

    安装npm install --save-dev jestnpm install babel-jest babel-core@^7.0.0-bridge.0 @babel/core regenerator-runtime babel-preset-env编辑package.json { "scripts": { "test": "jest" }}编辑.babelrc { ...

    Full-Snack-App-MERN:与FullSnackApp相同,但使用MERN而不是MEN

    FullSnackApp 评价您最喜欢的小吃。 技术要求 :check_mark: 至少有2个相关模型。...堆栈 ... [ regenerator-runtime ] [ sweetalert2 ] 用法 运行服务器端 npm start 运行客户端: parcel index.html

    KoAJAX:基于类似Koa中间件的HTTP客户端

    src =" https://polyfill.app/api/polyfill?features=es.string.match-all,es.object.from-entries,regenerator-runtime " &gt; &lt;/ script &gt; &lt;/ head &gt; 具有基于令牌的授权的RESTful API import { ...

    leetcode2sumc-leetcodeforjs:leetcodeforjs

    regenerator-runtime babel-preset-env //环境依赖 编辑package.json { "scripts": { "test": "jest" } } 编辑.babelrc { "presets": ["@babel/preset-env"] } 创建js文件 function sum(a, b) { return a + b; } ...

    详解小程序原生使用ES7 async/await语法

    小程序原生使用ES7 async / await 语法 小程序开发工具-详情-开启ES6转ES5 ...const regeneratorRuntime = require('./libs/runtime-module.js') 使用方法 Page({ /** * 页面的初始数据 */

    percent-calculator:这是一个百分比计算器,不再需要进行数学运算! [目前未设置UIUX]

    npm i -D parcel-bundler sass @babel/core sass @babel/core @babel/plugin-transform-runtime @babel/runtime-corejs2 --save-exact 用包裹添加通天塔 在babel.rc中添加 { "plugins": [ [ "@babel/plugin-...

    ember-maybe-import-regenerator:如果您尚未通过babel.includePolyfill将再生器运行时导入,则该余烬插件会导入再生器运行时

    这是一个插件,它将在Ember应用程序中导入 Runtime,但babel.includePolyfill是您尚未将babel.includePolyfill设置为true。 这对于以下用途很有用: 想要使用ES6生成器功能(包括async/await ),但又不想导入大约...

    esmodule-no-module-doing-something:用nomodulemodule做疯狂的事情

    esmodule没有模块在做某事用nomodule / module疯狂地做某事 传送两个输出 使用nomodule / module模式 以某种方式进行测试,即11-&gt;使用Parallels免费试用 成功传输输出(未找到与再生器运行时有关的要求错误) 带有...

Global site tag (gtag.js) - Google Analytics