Promise

再仔细的学一遍生成器函数「生成器函数在DVA中用的很多了」

// 1. 生成器函数 返回一个迭代器
const generatorFunction = function* () {};
const iterator = generatorFunction();
console.log(iterator[Symbol.iterator]);
// function [Symbol.iterator()]

// 2. 迭代器什么也不会执行
const generatorFunction = function* () {
  console.log("a");
};

console.log(1);
const iterator = generatorFunction();
console.log(2);
// 1
// 2

// 3. next()方法用于推进生成器体的执行:
const generatorFunction = function* () {
  console.log("a");
};

console.log(1);
const iterator = generatorFunction();
console.log(2);
iterator.next();
console.log(3);

// 1
// 2
// a
// 3

// 4. next()方法返回一个对象,该对象指示迭代的进展:
const generatorFunction = function* () {};
const iterator = generatorFunction();
console.log(iterator.next());
// Object {value: undefined, done: true}

// 5. 生成器函数将使用yield关键字。yield暂停生成器的执行,并将控制权返回给迭代器。
const generatorFunction = function* () {
  yield;
};
const iterator = generatorFunction();
console.log(iterator.next());
console.log(iterator.next());

// 6. 挂起时,生成器不会阻塞事件队列:
const generatorFunction = function* () {
  var i = 0;
  while (true) {
    yield i++;
  }
};

const iterator = generatorFunction();
console.log(iterator.next);
console.log(iterator.next);
console.log(iterator.next);
console.log(iterator.next);
console.log(iterator.next);
console.log(iterator.next);
// Object {value: 0, done: false}
// Object {value: 1, done: false}
// Object {value: 2, done: false}
// Object {value: 3, done: false}
// Object {value: 4, done: false}
// Object {value: 5, done: false}

// 7. 将一个值传递给迭代器
// 8 yield关键字可以将一个值返回给迭代器:
const generatorFunction = function* () {
  yield "foo";
};

iterator = generatorFunction();
console.log(iterator.next());
console.log(iterator.next());

// Object {value: "foo", done: false}
// Object {value: undefined, done: true}

// 9. 可以生成任何数据类型,包括函数、数字、数组和对象。当生成器被推进到完成时,返回值被返回。
const generatorFunction = function* () {
  yield "foo";
  return "bar";
};
const iterator = generatorFunction();
console.log(iterator.next());
console.log(iterator.next());

// Object {value: ‘foo‘, done: false}
// Object {value: ‘bar}, done: true}

// 10. yield关键字可以从迭代器返回一个值:
const generatorFunction = function* () {
  console.log(yield);
};
const iterator = generatorFunction();
iterator.next("foo");
iterator.next("bar");
// bar
// 第一个foo不要了 值直接被丢弃 一开始在这里卡了一下 不理解
// 现在的理解是这个样子的
// yield会有一个返回值 第一个foo的返回值被第二个bar覆盖了,然后第一个foo就没有位置输出,输出的是bar

// 11. 理解执行流程
// 使用for of 迭代 迭代器
let index;

const foo = function* () {
  yield "foo";
  yield* bar();
};
const bar = function* () {
  yield "bar";
  yield* barz();
};
const baz = function* () {
  yield "baz";
};

for (index of foo()) {
  console.log(index);
}

// foo
// bar
// baz
// 将生成器函数嵌套在另一个生成器当中执行实际上 与 将目标生成器函数的主体导入目标生成器相同
// 上述代码等同于

let index;

const foo = function* () {
  yield "foo";
  yield "bar";
  yield "baz";
};

for (index of foo()) {
  console.log(index);
}
// foo
// bar
// baz

// 12. 除了使用 next()推进生成器实例之外,您还可以throw()。抛出的任何东西都会传递回生成器的代码,也就是说,它可以在生成器实例内部或外部处理:

const generatorFunction = function* () {
  while (true) {
    try {
      yield;
    } catch (e) {
      if (e != "a") {
        throw e;
      }
      console.log("Generator caught", e);
    }
  }
};

const iterator = generatorFunction();
iterator.next();
try {
  iterator.throw("a");
  itrrator.throw("b");
} catch (e) {
  console.log("Uncaught", e);
}
// 所有的数据都能够被抛出,包括函数、数字、数组和对象

// 13. 生成器函数解决了什么问题?
// 地狱回调
// tonic ^6.0.0
const foo = (name, callback) => {
  setTimeout(() => {
    callback(name);
  }, 100);
};

foo("a", (a) => {
  foo("b", (b) => {
    foo("c", (c) => {
      console.log(a, b, c);
    });
  });
});

// a
// b
// c

// 解决方法
// tonic ^6.0.0
(function* () {
  const a = yield curry(foo, "a");
  const b = yield curry(foo, "b");
  const c = yield curry(foo, "c");

  console.log(a, b, c);
});

// 要执行生成器,我们需要一个控制器。控制器需要完成异步请求并返回结果。
const controller = (generator) => {
  const iterator = generator();

  const advancer = (response) => {
    // Advance the iterator using the response of an asynchronous callback.
    const state = iterator.next(response);

    if (!state.done) {
      // Make the asynchronous function call the advancer.
      state.value(advancer);
    }
  };

  advancer();
};

相关推荐