简体   繁体   English

有没有办法在javascript中创建类似python的生成器?

[英]Is there any way to create python-like generators in javascript?

In python if you loop over (or consume) an在 python 中,如果你循环(或消耗)一个

  1. iterator迭代器
  2. function return value函数返回值

you do not even know which one you have.你甚至不知道你拥有的是哪一个。 So it does not matter from the caller side if you have returned or yielded values from the callee to use in caller.因此,如果您从被调用者返回或产生值以在调用者中使用,则调用者方面并不重要。

However, as far as I know in javascript if you want to use yield, you have to explicitly mark the function* with an asterisk and can not treat the computed value the same way as a "regular function's return value" on the caller side.然而,据我所知,如果你想在 javascript 中使用 yield,你必须用星号显式地标记函数*,并且不能像调用方的“常规函数的返回值”一样对待计算值。

Is there an abstraction in javascript to hide these differences to get the same nice abstraction which python has? javascript 中是否有抽象来隐藏这些差异以获得与 python 相同的漂亮抽象?

There are several constructs in JavaScript where the caller does not need to know whether the called function is a generator, or a plain function that returns an array, string, Map, ...etc. JavaScript 中有几种结构,调用者不需要知道被调用的函数是生成器,还是返回数组、字符串、Map 等的普通函数。 These return values all have in common that they are iterable.这些返回值都有一个共同点,它们都是可迭代的。

Here are two examples on how you can treat the return value of such a function:以下是关于如何处理此类函数的返回值的两个示例:

  1. Iterate through the values:遍历值:

     for (let x of f()) { // ... }

    Depending on what f() returns, x will be the following:根据f()返回的内容, x将如下所示:

    • Iterate a string: get each character迭代一个字符串:获取每个字符
    • Iterate an array: get each element of it迭代一个数组:获取它的每个元素
    • Iterate a Map: get each key/value pair of it迭代一个 Map:获取它的每个键/值对
    • Iterate an iterator (maybe returned by a generator): get each yielded value from it迭代迭代器(可能由生成器返回):从中获取每个产生的值
    • ... ...
  2. Create an array from the values:从值创建一个数组:

     const copy = Array.from(f());

    Or also:或者也:

     const copy = [...f()];

    NB: the nice thing of Array.from is that it accepts a callback function as a second argument: a mapper called for each value.注意: Array.from是它接受一个回调函数作为第二个参数:一个为每个值调用的映射器。

  3. Spread the values as arguments to another function将值作为参数传播到另一个函数

    If the values are numerical:如果值是数字:

     Math.min(...f());

    As Math.min can accept multiple arguments (not just two), this gives the minimum value of the whole series (as min does in Python).由于Math.min可以接受多个参数(不仅仅是两个),这给出了整个系列的最小值(如min在 Python 中所做的那样)。

Read more about iterators and iterables on MDN 在 MDN 上阅读有关迭代器和可迭代对象的更多信息

SINCE ES6 :从 ES6 开始

There is a new "generator" function , which works almost exactly like generators in Python.一个新的“生成器”函数,它的工作原理几乎与 Python 中的生成器完全一样。 From MDN:来自 MDN:

function* generator(i) {
  yield i;
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value);
// expected output: 10

console.log(gen.next().value);
// expected output: 20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM