根本不常用知识之Generator
function isPromise(obj: any) {
  return typeof obj.then === "function";
}
function isGenerator(obj: any) {
  return typeof obj.next === "function" && typeof obj.throw === "function";
}
function isGeneratorFunction(obj: any) {
  const { constructor } = obj;
  if (!constructor) return false;
  if ([constructor.name, constructor.displayName].includes("GeneratorFunction"))
    return true;
  return isGenerator(constructor.prototype);
}
//上面三个是co库原生的校验
export default function co(gen) {
  return new Promise((resolve, _reject) => {
    typeof gen === "function" && (gen = gen());
    function next(data) {
      const ret = gen.next(data);
      if (ret.done) return resolve(ret.value);
      toPromise(ret.value).then(next);
    }
    function toPromise(obj) {
      if (isPromise(obj)) return obj;
      if (isGeneratorFunction(obj) || isGenerator(obj)) return co(obj);
      // if (other types) {}
      return; // error
    }
    next();
  });
}
function* gen() {}
const gObj = gen();
gObj.next();
gObj.return();
Object.getPrototypeOf(gen).constructor // GeneratorFunction {prototype: Generator, ...}
const GeneratorFunction = Object.getPrototypeOf(gen).constructor;
const gen = new GeneratorFunction('a', 'yield a * 2');
class GeneratorFunction {}
// GeneratorFunction 的 prototype 很通用,单独拎出来
class GeneratorFunctionPrototype {
  static [Symbol.toStringTag] = "GeneratorFunction";
  // 实现 iterator protocol
  next(args) {}
  return(args) {}
  throw(args) {}
  // 实现 iterable protocol
  [Symbol.iterator]() {
    return this;
  }
}
// 相互引用
GeneratorFunctionPrototype.constructor = GeneratorFunction;
GeneratorFunction.prototype = GeneratorFunctionPrototype;
// 作用不大,设置 prototype 即可
//class Generator {}
//Generator.prototype = GeneratorFunctionPrototype.prototype;
async function a() {}
function* b() {}
// babel 编译后
function asyncGeneratorStep(gen, resolve, reject, _next, ...) {
  // 调用 gen 的 next 或 throw 方法
  var info = gen[key](arg);
  var value = info.value;
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}
function _asyncToGenerator(fn) {
  return function () {
    return new Promise(function (resolve, reject) {
      // 获取 generator 对象
      var gen = fn.apply(self, arguments);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      // 初始化执行 next
      _next(undefined);
    });
  };
}
以下代码基本都是babel的简写或粘贴过来的直接看babel编译过的也一样
  let num = 0;
  async function gen() {
    num = num + (await wait(10));
    // num = (await wait(10)) + num;
    await foo();
    return num;
  }
  async function foo() {
    await "wangshun";
  }
  (async () => {
    // debugger;
    await gen();
    console.log("ws: res", num);
  })();
function _callee$(_context) {
  while (1) {
    switch (_context.next) {
      case 0:
        // await wait(10)
        _context.next = 3;
        return wait(10);
      case 3:
        // await 123
        _context.next = 7;
        return 123;
      case 7:
        _context.next = 9;
        // await foo()
        return foo();
      case "end":
        return _context.stop();
    }
  }
}
function _foo() {
  _foo = _asyncToGenerator(
    regeneratorRuntime.mark(function _callee2() {
      return regeneratorRuntime.wrap(function _callee2$(_context2) {
        switch (_context2.next) {
          case 0:
            _context2.next = 2;
            return "literal";
          case "end":
            return _context2.stop();
        }
      }, _callee2);
    })
  );
  return _foo.apply(this, arguments);
}
function mark(genFn: () => void) {
  return _inheritsLoose(genFn, GeneratorFunctionPrototype);
}
function _inheritsLoose(subClass, superClass) {
  Object.setPrototypeOf(subClass, superClass);
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype.constructor = subClass;
  return subClass;
}
type GeneratorMethod = "next" | "return" | "throw";
class GeneratorFunctionPrototype {
  private _invoke: (method: GeneratorMethod, args) => { value: any, done: boolean };
  // 注意这是原型方法哦
  next(args) {
    return this._invoke("next", args);
  }
  return(args) {
    return this._invoke("return", args);
  }
  throw(args) {
    return this._invoke("throw", args);
  }
}
async function a() {
  const res = await b();
}
async function b() {
  await 1;
  await 'str';
  return { data: 'lawler', msg: 'ok' };
}
function gen$(_context) {
  switch (_context.next) {
    case 0:
      _context.next = 7;
      return wait(10);
    case 7:
      // 传递 foo generator object 给 gen 的 context
      return _context.delegateYield(foo(), "t2", 8);
    case "end":
      return _context.stop();
  }
}
generator._invoke = function invoke(method, args) {
  context.method = method;
  // yield* genFn 时使用,循环返回 genFn 迭代的结果,直到 return
  while (true) {
    const delegate = context.delegate;
    if (delegate) {
      const delegateResult = maybeInvokeDelegate(delegate, context);
      if (delegateResult) {
        if (delegateResult === empty) continue;
        // 传出内部迭代结果 { value, done }
        return delegateResult;
      }
    }
  }
  if (method === "next") {}
}
                    
                
                
            
        
浙公网安备 33010602011771号