美文网首页程序员
ES5 实现 ES6 生成器 (下)

ES5 实现 ES6 生成器 (下)

作者: 老邵 | 来源:发表于2018-10-14 17:36 被阅读11次

在上一篇文章中,我们简单了解了 ES6 生成器。在这一篇文章章中,我将使用 ES5 的代码实现 ES6 生成器的部分功能。推荐大家去阅读《你不知道的 JavaScript 中卷》,书上有关于生成器的更详细的介绍,我下面用到的代码是书上的示例代码。

要实现一个生成器,我们首先要确定需要实现哪几个功能,然后再一步步实现。这里重点实现两个功能:数据的双向传递和暂停。

 function *func() {
  var num = yield '传出的值';
 console.log(num);
 }

ES6 生成器的代码像上面这样。由于代码都是顺序执行的,如果想要实现暂停,我们就要能够保存状态。可以用一个名为 state 的变量保存状态。但是,如何在生成器外部调整状态呢?这里我们用到了闭包。

具体代码实现如下,若函数 foo 是一个生成器,它首先要返回一个对象,该对象包括一个 next 函数,调用函数可以返回 value

   return {
       next:function(v) {
                     return {
                             value:........
                            }
            },
   }

其次,foo 要包含一个处理不同状态的程序,可以用 switch 语句实现:

   // 管理生成器状态
var state;

// 生成器变量范围声明
var val;

//处理每个状态
function process(v) {
    switch (state) {
        case 1:
            return '传出的值';
        case 2:
            val = v;
            console.log(val);
            return;
        case 3:
            var err = v;
            console.log("oops:", err);
            return false;
    }
}

然后,在 next 函数中针对不同的状态进行处理:

                 if (!state) {
            state = 1;
            return {
                done: false,
                value: process(),  //第一个状态返回对象的 value 为 request(url)
            }
        }
        // yield 恢复 
        else if (state == 1) {
            state = 2;
            return {
                done: true,       // 第二个状态表示第二次调用 next ,此时生成器为完成状态
                value: process(v) // 第二个状态返回的对象的 value 为 undefined
            }
        }
        // 此处生成器已经完成
        else {
            return {
                done: true,
                value: undefined
            }
        }

代码整合为:

                 function foo(url) {
// 管理生成器状态
var state;

// 生成器变量范围声明
var val;

//处理每个状态
function process(v) {
    switch (state) {
        case 1:
            return '传入的值';
        case 2:
            val = v;
            console.log(val);
            return;
        case 3:
            var err = v;
            console.log("oops:", err);
            return false;
    }
}

return {
    // 此处利用了闭包来保存状态,每次调用 next 都会进入不同的状态,模拟了迭代器的功能
    next: function(v) {
        // 初始状态,执行到 yield
        if (!state) {
            state = 1;
            return {
                done: false,
                value: process(),  //第一个状态返回对象的 value 为 request(url)
            }
        }
        // yield 恢复 
        else if (state == 1) {
            state = 2;
            return {
                done: true,       // 第二个状态表示第二次调用 next ,此时生成器为完成状态
                value: process(v) // 第二个状态返回的对象的 value 为 undefined
            }
        }
        // 此处生成器已经完成
        else {
            return {
                done: true,
                value: undefined
            }
        }
    }
  
       var it = foo(3);
      it.next();
      it.next(6);

这段代码与最上方 ES6 生成器代码的功能相同。

相关文章

网友评论

    本文标题:ES5 实现 ES6 生成器 (下)

    本文链接:https://www.haomeiwen.com/subject/tmnzaftx.html