迭代器和JavaScript中的生成器? [英] Iterator and a Generator in Javascript?

查看:98
本文介绍了迭代器和JavaScript中的生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Mozilla页面上,迭代器和生成器有一个声明:


虽然自定义迭代器是一个有用的工具,但由于需要明确维护他们的自定义迭代器,它们的创建需要
精心编程
内部状态。发电机提供了一个强大的替代方案:它们允许
通过编写一个单独的函数
定义一个迭代算法,它可以保持自己的状态。


关于上述说明,不可能在没有生成器的情况下编写迭代算法,例如:

  Array [Symbol.iterator] = function(){
return {
next:function(){
// logic
return {
value:
done:false
}
}
}
}

不能让我的头晕有人可以解释他们创造替代品的主要原因是什么,似乎与我没有什么不同。

解决方案

他们可能看起来很相似表面上,但它们可以以非常不同的方式使用。



迭代器和迭代器


$ b $迭代器是相当严格的定义:它们是对象(迭代器),它包含一个 next (和可能还有一些其他的)函数。每次调用 next 函数时,它将返回一个具有两个属性的对象:




  • value :迭代器的当前值

  • done :迭代器是否完成?



另一方面,一个迭代是一个具有$ code> Symbol.iterator 键(代表知名符号 @@ iterator )。该键包含一个函数,当被调用时返回一个新的迭代器。
一个迭代的例子:

  const list = {
entries:{0:'a' ,1:'b'},
[Symbol.iterator]:function(){
let counter = 0;
const entries = this.entries;
return {
next:function(){
return {
value:entries [counter],
done:!entries.hasOwnProperty(counter ++)
}
}
}
}
};

他们的主要目的是提供可以重复的接口: p>

  for(let item of list){console.log(item); } 
//'a'
//'b'

发电机



另一方面,发电机更为通用。它有助于将它们视为可以暂停和恢复的功能。



虽然可以迭代它们(它们的迭代提供一个下一个方法),他们可以实现更复杂的程序,并通过他们的下一个方法提供输入/输出通信。



一个简单的生成器:

  function * mygen(){
var myVal = yield 12;
return myVal * 2;
}

const myIt = mygen();

const firstGenValue = myIt.next()。
//生成器暂停并产生第一个值

const result = myIt.next(firstGenValue * 2).value;

console.log(result); // 48

生成器委托



生成器可以委托给另一个生成器:

  function * mydelgen(val){
yield val * 2;
}

函数* mygen(){
var myVal = yield 12;
yield * mydelgen(myVal); //委托给另一个生成器
}

const myIt = mygen();
const val = myIt.next()。value;
console.log(val);
console.log(myIt.next(val).value);
console.log(myIt.next()。value);

发电机和承诺



生成器和承诺可以通过诸如 co <​​/a>。

  co(function *(){
//并行解决多个承诺
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]
} ).catch(的onerror);

结论



因此,总而言之,可以说,迭代器的主要目的是为自定义对象创建一个要迭代的接口,而生成器为同步和异步工作流提供了大量的可能性:





等。


On Mozilla's page iterators and generators there is a statement:

While custom iterators are a useful tool, their creation requires careful programming due to the need to explicitly maintain their internal state. Generators provide a powerful alternative: they allow you to define an iterative algorithm by writing a single function which can maintain its own state.

Regarding above explanation, isn't it possible to write an iterative algorithm without Generators, such as:

Array[Symbol.iterator] = function(){
    return {
        next: function(){
            //logic
            return {
                value: "",
                done:false
            }
        }
    }
}

Can't get my head around. Could someone explain what is the main reason they created an alternative, seems not much different to me.

解决方案

They might look pretty similar on the surface, but they can be used in very different ways.

Iterators and Iterables

Iterators are rather strictly defined: they are object (the iterators) which contains a next (and possibly a few other) function. Every time the next function is called, it is expected to return an object with two properties:

  • value: the current value of the iterator
  • done: is the iterator finished?

An iterable on the other hand is an object which has a property with a Symbol.iterator key (which represents the well know symbol @@iterator). That key contains a function, which when called, returns a new iterator. An example of an iterable:

const list = {
    entries: { 0: 'a', 1: 'b' },
    [Symbol.iterator]: function(){
        let counter = 0;
        const entries = this.entries;
        return {
            next: function(){
                return {
                    value: entries[counter],
                    done: !entries.hasOwnProperty(counter++)
                }
            }
        }
    }
};

Their main purpose, as their name suggests, is to provide an interface which can be iterated:

for (let item of list) { console.log(item); }
// 'a'
// 'b'

Generators

Generators on the other hand are much more versatile. It helps to think of them as functions which can be paused and resumed.

While they can be iterated (their iterables provide a next method), they can implement much more sophisticated procedures and provide a input/output communication through their next method.

A simple generator:

function *mygen () {
   var myVal = yield 12;
   return myVal * 2;
}

const myIt = mygen();

const firstGenValue = myIt.next().value;
// Generator is paused and yields the first value

const result = myIt.next(firstGenValue * 2).value;

console.log(result); // 48

Generator delegation

Generators can delegate to another generator:

function *mydelgen(val) {
    yield val * 2;
}

function *mygen () {
    var myVal = yield 12;
    yield* mydelgen(myVal); // delegate to another generator
}

const myIt = mygen();
const val = myIt.next().value;
console.log(val);
console.log(myIt.next(val).value);
console.log(myIt.next().value);

Generators & Promises

Generators and Promises together can create a sort of automatic asynchronous iterator with the help of utilities such as co.

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]
}).catch(onerror);

In Conclusion

So in conclusion one could say that the main purpose of iterators is to create an interface for custom objects to be iterated, whereas generators provide a plethora of possibilities for synchronous and asynchronous workflows:

  • stateful functions
  • generator delegation
  • generators & promises
  • CSP

etc.

这篇关于迭代器和JavaScript中的生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆