Generator 实现

Generator 是 ES6 中新增的语法,和 Promise 一样,都可以用来异步编程

  1. // 使用 * 表示这是一个 Generator 函数
  2. // 内部可以通过 yield 暂停代码
  3. // 通过调用 next 恢复执行
  4. function* test() {
  5. let a = 1 + 2;
  6. yield 2;
  7. yield 3;
  8. }
  9. let b = test();
  10. console.log(b.next()); // > { value: 2, done: false }
  11. console.log(b.next()); // > { value: 3, done: false }
  12. console.log(b.next()); // > { value: undefined, done: true }

从以上代码可以发现,加上 * 的函数执行后拥有了 next 函数,也就是说函数执行后返回了一个对象。每次调用 next 函数可以继续执行被暂停的代码。以下是 Generator 函数的简单实现

  1. // cb 也就是编译过的 test 函数
  2. function generator(cb) {
  3. return (function() {
  4. var object = {
  5. next: 0,
  6. stop: function() {}
  7. };
  8. return {
  9. next: function() {
  10. var ret = cb(object);
  11. if (ret === undefined) return { value: undefined, done: true };
  12. return {
  13. value: ret,
  14. done: false
  15. };
  16. }
  17. };
  18. })();
  19. }
  20. // 如果你使用 babel 编译后可以发现 test 函数变成了这样
  21. function test() {
  22. var a;
  23. return generator(function(_context) {
  24. while (1) {
  25. switch ((_context.prev = _context.next)) {
  26. // 可以发现通过 yield 将代码分割成几块
  27. // 每次执行 next 函数就执行一块代码
  28. // 并且表明下次需要执行哪块代码
  29. case 0:
  30. a = 1 + 2;
  31. _context.next = 4;
  32. return 2;
  33. case 4:
  34. _context.next = 6;
  35. return 3;
  36. // 执行完毕
  37. case 6:
  38. case "end":
  39. return _context.stop();
  40. }
  41. }
  42. });
  43. }