首页 > 解决方案 > 我可以在 JavaScript 中获取生成器的当前值吗?

问题描述

假设我想在单击时为我的按钮旋转类名。点击一次变成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);
});

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

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

当然,我可以自己保留这个值并使用它。同样,我可以清除我rotator()自己使用的所有类。我什至可以使我的生成器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 中读取生成器函数的当前值吗?如果不是,是否在不需要时避免使用内存(这个值可能非常大)?

标签: javascriptgeneratoryield

解决方案


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

不。

但是,如果您愿意,您可以自己轻松地实现这一点。

如果不是,是否在不需要时避免使用内存?

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

但我认为设计中没有可用字段的主要原因是.current从理论上讲它没有意义:在迭代开始之前,或者在迭代器耗尽之后,该字段会有什么值?可以选择undefined,但简洁的设计根本没有该字段,并且仅在您实际执行迭代器时才返回值。


推荐阅读