遍历和迭代是很类似的两个概念,遍历就是在一个东西内循环的拿数据,而迭代则是在遍历的过程中进行一次程序上的输出,也就是说迭代是遍历的一个步骤。

    写一个生成器函数:

    1. var arr = [1, 2, 3, 4, 5, 6];
    2. function* test() {
    3. for (const iterator of arr) {
    4. // yield 具有停止的作用
    5. yield iterator;
    6. }
    7. }
    8. // iter 就是一个迭代器 iterator
    9. let iter = test();
    10. // 迭代器具有 next 方法,返回本次迭代的数据
    11. console.log(iter.next()); // {value: 1, done: false}
    12. console.log(iter.next()); // {value: 2, done: false}

    假如现在有一个需求,有 5 个函数需要依次执行,改怎么做呢?当然你肯定想到遍历执行。

    1. var functions = [
    2. function test1() {
    3. console.log("test1");
    4. },
    5. function test2() {
    6. console.log("test2");
    7. },
    8. function test3() {
    9. console.log("test3");
    10. },
    11. function test4() {
    12. console.log("test4");
    13. },
    14. function test5() {
    15. console.log("test5");
    16. }
    17. ];
    18. for (const iterator of functions) {
    19. iterator();
    20. }
    21. // test1
    22. // test2
    23. // test3
    24. // test4
    25. // test5

    那么我想在执行完test3的时候停止执行又该怎么办呢?首先想到的肯定是break,但是怎么知道执行到test3函数呢?要不给函数加个返回布尔值试试。

    1. var functions = [
    2. function test1() {
    3. console.log("test1");
    4. return true;
    5. },
    6. function test2() {
    7. console.log("test2");
    8. return true;
    9. },
    10. function test3() {
    11. console.log("test3");
    12. return false;
    13. },
    14. function test4() {
    15. console.log("test4");
    16. return true;
    17. },
    18. function test5() {
    19. console.log("test5");
    20. return true;
    21. }
    22. ];
    23. for (const iterator of functions) {
    24. if (!iterator()) break;
    25. }
    26. // test1
    27. // test2
    28. // test3

    这样就实现了函数执行的中止操作。

    NodeJS中有个东西叫做「中间件」。假如有个需求用户访问/user页面的时候需要进行一系列的判断,如果某个判断存在问题需要跳转到登录页
    生成器和迭代器的应用 - 图1
    这个时候如果还使用return false就不合适了,可以利用Koa中间件函数中的next方法,当调用next方法后再继续执行后面的函数。

    1. var functions = [
    2. function test1(next) {
    3. console.log("test1");
    4. next();
    5. },
    6. function test2(next) {
    7. console.log("test2");
    8. next();
    9. },
    10. function test3(next) {
    11. console.log("test3");
    12. // 假如判断是否有 token
    13. if (true) {
    14. next();
    15. }
    16. },
    17. function test4(next) {
    18. console.log("test4");
    19. next();
    20. },
    21. function test5(next) {
    22. console.log("test5");
    23. next();
    24. },
    25. ];
    26. (function (functions) {
    27. // 生成器函数
    28. function* generator(arr) {
    29. for (const iterator of arr) {
    30. yield iterator;
    31. }
    32. }
    33. const iter = generator(functions);
    34. const init = () => {
    35. nextDo(iter.next());
    36. };
    37. // 第一次执行,n 等于 {value: fun, done: false}
    38. // 然后执行第 4 行的 next(),相当于这里的匿名函数执行
    39. // 匿名函数执行,会继续进行迭代,然后再判断...
    40. function nextDo(n) {
    41. n.value(function () {
    42. const n = iter.next();
    43. if (!n.done) {
    44. nextDo(n);
    45. } else {
    46. return;
    47. }
    48. });
    49. }
    50. init();
    51. })(functions);