js generator和yield

function co<T>(fn: () => Generator<any, any, any>): Promise<T> {
  const g: Generator = fn();
  return new Promise((resolve, reject) => {
    const r = g.next();
    _next(r, resolve);
  });

  function _next(v: IteratorResult<any, any>, done: any): any {
    if (v.done) {
      return done(v.value);
    }
    const isArray = Array.isArray(v.value);
    Promise.all(isArray ? v.value : [v.value]).then((value) => {
      const r: IteratorResult<any, any> = g.next(isArray ? value : value[0]);
      return _next(r, done);
    });
  }
}

// 返回promise数据
function getData(): Promise<any> {
  return Promise.resolve({ name: "ajanuw" });
}

// 返回generator数据
function* getData2(): Generator<any, any, any> {
  return yield { code: 1 };
}

co(function* (): Generator<any, any, any> {
  // next(value) == r1
  const r1 = yield 1; // 当执行next()时获取的返回值1
  const r2 = yield getData();
  const r3 = yield* getData2() as any;
  return [r1, r2, r3]; 
}).then((r) => {
  console.log(r); // 1 {name: "ajanuw"} {code: 1}
});

co(function* () {
  // resolve multiple promises in parallel
  var a = Promise.resolve(1);
  var b = Promise.resolve(2);
  var c = Promise.resolve(3);
  var res = yield [a, b, c];
  console.log(res);
  // => [1, 2, 3]
});

函数返回 IterableIterator

export function iter_unpack() {
  const arr = ["a", "b", "c"];
  return {
    next() {
      const value = arr.shift();
      return { value, done: !value };
    },
    [Symbol.iterator](): IterableIterator<any> {
      return this;
    },
  };
}

const r = iter_unpack();
for (const i of r) {
  console.log(i); // 分别打印 a,b,c
}

迭代class可以实现[Symbol.iterator]函数

export class ClassList  implements ArrayLike<string> {
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.length) {
          return {
            done: false,
            value: this[index++],
          };
        } else {
          return {
            done: true,
          };
        }
      },
    };
  }
}
原文地址:https://www.cnblogs.com/ajanuw/p/12677955.html