You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ES6 Proxy实现生成器函数的链式调用?

Got it, let's break this down—using Proxy to add chainable array-like methods to generators is such a cool learning project. Here's a working solution that keeps the generator's lazy evaluation while letting you chain map, filter, and forEach just like you want:

Step 1: The Core Proxy Wrapper

First, we'll create a proxy that tracks your chainable operations and only executes them when you trigger a terminal method like forEach.

function generatorProxy(generatorOrFunc, ...args) {
  // If we get a generator function, run it with provided args to get an iterator
  const generator = typeof generatorOrFunc === 'function' 
    ? generatorOrFunc(...args) 
    : generatorOrFunc;
  
  // Store the sequence of map/filter operations to apply later
  const operations = [];

  const proxy = new Proxy({}, {
    get(target, prop) {
      // Terminal method: Execute all operations and iterate over results
      if (prop === 'forEach') {
        return (callback) => {
          for (const value of generator) {
            let current = value;
            let shouldKeep = true;

            // Apply each stored operation in order
            for (const op of operations) {
              if (op.type === 'map') {
                current = op.fn(current);
              } else if (op.type === 'filter') {
                if (!op.fn(current)) {
                  shouldKeep = false;
                  break;
                }
              }
            }

            if (shouldKeep) {
              callback(current);
            }
          }
        };
      }

      // Chainable method: Add map operation to the queue
      if (prop === 'map') {
        return (fn) => {
          operations.push({ type: 'map', fn });
          return proxy; // Return the proxy to keep chaining
        };
      }

      // Chainable method: Add filter operation to the queue
      if (prop === 'filter') {
        return (fn) => {
          operations.push({ type: 'filter', fn });
          return proxy;
        };
      }

      // Fallback for any other properties
      return Reflect.get(target, prop);
    }
  });

  return proxy;
}

Step 2: Test with a Range Generator

Let's define a simple range generator to test our proxy:

function* range(start, end) {
  for (let i = start; i < end; i++) {
    yield i;
  }
}

Step 3: Use the Chainable Generator

Now you can use it exactly like you described:

// Chain map, filter, and forEach
generatorProxy(range, 1, 10)
  .map(num => num * 2)
  .filter(num => num > 10)
  .forEach(num => console.log(num));

// Output: 12, 14, 16, 18

How It Works

  • Lazy Evaluation: The generator doesn't start producing values until you call forEach—all map and filter operations are just stored in a queue until then.
  • Proxy Interception: The Proxy catches access to map, filter, and forEach. For chainable methods, it adds the operation to the queue and returns the same proxy to keep the chain going. For forEach, it iterates through the generator, applies all stored operations, and runs your callback on the final values.
  • No Prototype Modifications: We're not touching Generator.prototype at all—all logic is encapsulated in the proxy wrapper.

Bonus: Extend to Other Methods

You can easily add more chainable or terminal methods, like reduce:

// Inside the Proxy's get handler:
if (prop === 'reduce') {
  return (fn, initialValue) => {
    let accumulator = initialValue;
    for (const value of generator) {
      let current = value;
      for (const op of operations) {
        if (op.type === 'map') current = op.fn(current);
        else if (op.type === 'filter' && !op.fn(current)) {
          current = null;
          break;
        }
      }
      if (current !== null) {
        accumulator = accumulator === undefined ? current : fn(accumulator, current);
      }
    }
    return accumulator;
  };
}

// Usage:
const sum = generatorProxy(range, 1, 5)
  .map(num => num * 3)
  .reduce((acc, num) => acc + num);
// sum = 3+6+9+12 = 30

内容的提问来源于stack exchange,提问作者shu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:44:50