简体   繁体   中英

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

In python if you loop over (or consume) an

  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.

Is there an abstraction in javascript to hide these differences to get the same nice abstraction which python has?

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. 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:

    • Iterate a string: get each character
    • Iterate an array: get each element of it
    • Iterate a Map: get each key/value pair of it
    • 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.

  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).

Read more about iterators and iterables on MDN

SINCE ES6 :

There is a new "generator" function , which works almost exactly like generators in Python. From 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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