我可以在 JavaScript 中获取生成器的当前值吗?

Can I get the current value of generator in JavaScript?

假设我想在点击时为我的按钮旋转 class 名称。单击一次变为 button-green,单击两次 - button-yellow,三次 - button-red。然后它会重复,所以第四次点击会使它再次 button-green

我知道其他技术如何做到这一点,我不是在寻求实施建议。我编写了这个示例以了解有关 JavaScript.

中生成器的一些信息

这是我的生成器代码:

function* rotator(items) {
    while (true) {
        for (const item of items) {
            yield item;
        }
    }
}

const classRotator = rotator([
    'button-green',
    'button-yellow',
    'button-red',
]);

document.getElementById('my-button').addEventListener('click', event => {
    event.currentTarget.classList.add(classRotator.next().value);
});

它工作正常,除了它永远不会摆脱以前的 class。最方便的方法是在获取下一个之前读取当前状态:

// .current is not a thing:
event.currentTarget.classList.remove(classRotator.current);

这个值我当然可以自己留着用。同样,我可以自己清除 rotator() 中使用的所有 classes。我什至可以让我的生成器函数 yield 以前和当前值:

function* rotator(items) {
    let previous;

    while (true) {
        for (const item of items) {
            yield {
                item,
                previous
            };

            previous = item;
        }
    }
}

然后像这样使用它:

document.getElementById('my-button').addEventListener('click', event => {
    const {item: className, previous: previousClassName} = classRotator.next().value;

    event.currentTarget.classList.remove(previousClassName);
    event.currentTarget.classList.add(className);
});

但这不是重点 - 出于教育目的,我问这个问题:

我可以在JavaScript中读取生成函数的当前值吗?如果不是,是不是为了避免在不需要的时候使用内存(这个值可能会很大)?

JavaScript“本地人”API通常愿意疯狂地创造新对象。从表面上看,保存记忆通常不是语言委员会的基本目标。

创建一个通用工具将调用生成器的结果包装在一个对象中将非常简单,该对象将 .next() 方法委托给实际结果对象,但还将每个返回值保存为 .current() 值(或任何适用于您的应用程序的值)。拥有 .current() 有用的,例如用于编程语言的词法分析器。但是,基本生成器 API 并未对此做出规定。

Can I read the current value of generator function in JavaScript?

没有

但如果你愿意,你可以

If not, is it to avoid using memory when it's not needed?

也许吧。迭代器应该不依赖于它生成的最后一个值,以允许独立的垃圾收集并降低保留耗尽或尚未完成的生成器的成本。

但我认为设计中没有 .current 字段的主要原因是从理论上讲它没有意义:在迭代开始之前该字段有什么价值,或者迭代器耗尽后?人们可能会选择 undefined,但如果您实际执行迭代器,干净的设计根本就没有字段,只有 returns 值。