观察者没有被取消——如何对 takeEvery 进行最终取消的检测

Watchers not getting canceled - how to do a finally-cancelled detection on takeEvery

我这样开始多个"watchers":

yield allMyTasks = [fork(fooWatcher), fork(barWatcher), fork(bazWatcher), fork(quxWatcher)];

这些都开始一个takeEvery这样的:

function* fooWatcher() {
    try {
        yield takeEvery('FOO', fooWorker);
    } finally {
        if (yield cancelled()) {
            console.log('fooWatcher was cancelled');
        }
    }
}

注销时,我这样取消 allMyTasks

yield cancel(...allMyTasks);

然而 none 的 finally 个区块由于 cancelled 而发生。有没有办法检测观察者的取消?

我测试了调度 FOO 以测试 takeEverycancel 之后是否仍然存在,并注意到即使 finally-cancelled 没有触发,takeEvery 真的没有反应。所以真的取消了吗这个观察是否正确?这就是我所希望的,但是当 takeEvery 被取消时我需要做一个 finally-cancelled

问题是 takeEvery 助手是非阻塞的,所以解释器不会在 try 块内等待,当 finally 块中的代码被立即调用传奇是 运行.

要使 cancelled 效果生效,您需要仍在 try 方块中等待某事。

可能有更聪明的写法,但实现您想要的一种方法是等待一个永远不会实现的承诺 resolved/rejected。 (注意某些 Promise 库可能默认开启的 Promise 超时)。

function* fooWatcher() {
    try {
        yield takeEvery('FOO', fooWorker);
        yield new Promise(()=>{});
    } finally {
        if (yield cancelled()) {
            console.log('fooWatcher was cancelled');
        }
    }
}

等待一个永远不会被分派的动作也可以工作,尽管我仍然认为还有一些其他明显的方法可以永远等待。