javascript - redux saga channel 关闭后如何运行同步代码

标签 javascript redux-saga

我正在尝试在 saga 取消/关闭后或 channel 关闭后执行代码。

这是一个简单的例子:

  1. 创建一个包含一些随机数的 channel
  2. 创建一些 fork 对每个数字进行一些昂贵的计算。
  3. 向 channel 添加一些随机数
  4. channel 关闭后,我想执行一些代码。

但我缺少的是如何在所有这些完成后执行代码。(在这个例子中,一个简单的 console.log)

代码在这里:

const {
    take, fork, put, call, delay, all, join,
} = require('redux-saga/effects');
const { channel, runSaga } = require('redux-saga');

function* doSomeExpensiveThing(citiesChannel) {
    while (true) {
        const payload = yield take(citiesChannel);

        // do some expensive operation with each number
        // simulated here with a random 0-1000ms delay
        yield delay(Math.floor(Math.random() * Math.floor(10)) * 100);
        console.log('Finished number: ', payload);
    }
}

function* bootstrapSaga(numberOfWorkers) {
    console.log('Bootrstrapping saga.');

    // create a channel to queue all incoming numbers
    const numbersQueue = yield call(channel);
    const workers = [];

    // create N worker 'threads' to receive items put into the queue
    for (let i = 0; i < numberOfWorkers; i += 1) {
        workers.push(yield fork(doSomeExpensiveThing, numbersQueue));
    }

    const allNumbers = Array.from(Array(10).keys());

    // add all numbers to the queue
    while (allNumbers.length > 0) {
        yield put(numbersQueue, allNumbers.pop());
    }

    // yield join(workers);
    // yield all(workers.map(w => w.toPromise()));
    // console.log('NEVER HAPPENS');
}

function* mainSaga(numberOfWorkers = 3) {
    console.log('Starting...');

    yield call(bootstrapSaga, numberOfWorkers);
    console.log('ALL DONE.'); // Y U NO WORK?? ¯\_(ツ)_/¯ 
}

runSaga({}, mainSaga, 5);

如果它更容易,这里有一个可运行的版本: https://codesandbox.io/s/o40kl 一定要在codesandbox上打开控制台

对于这个例子,我尝试了一些方法,比如使用 yield all(workers)yield join(workers)。这些只是使 console.log('ALL DONE') 工作的尝试。

问题:我必须对我的脚本进行哪些修改才能使其这样做?

最佳答案

更新:为了让它工作,我们需要在放置工作人员完成的工作后关闭 channel :

numbersQueue.close();

然后我们可以使用all效果来等待所有任务完成:

yield all(workers.map(w => w.toPromise()));

Creates an Effect description that instructs the middleware to run multiple Effects in parallel and wait for all of them to complete. It's quite the corresponding API to standard Promise#all.

更新:我已经更新了这个codesandbox并添加了必要的修改,以便您可以看到它按预期工作。

enter image description here

关于javascript - redux saga channel 关闭后如何运行同步代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56652466/

相关文章:

javascript - 多个 redux-sagas

javascript - ASP.NET MVC Javascript 在页面加载时第一次未触发

javascript - 打包应用中的 Chrome 通知。 "chrome.notifications.create"

javascript - React-Redux 可以不用react-saga 或react-thunk 框架吗?

javascript - 生成器函数不显示我的数据,如何访问它?

reactjs - 访问 saga 中的 store.dispatch 以与 React router redux 一起使用

reactjs - 用于经过身份验证的 React 组件和路由的更好模式

javascript - 如何为单击的按钮分配值

javascript - 解析和替换 HTML 中文本的最佳方法是什么?

javascript - 在 javascript 中将包含 HTML 的哈希树解析为 JSON