redux saga通道关闭后如何运行同步代码

时间:2019-06-18 15:26:40

标签: javascript redux-saga

我想在取消/关闭传奇故事或关闭频道之后执行代码。

这是一个简单的示例:

  1. 创建一个包含一些随机数的频道
  2. 创建一些分叉以对每个数字进行一些昂贵的计算。
  3. 在频道中添加一些随机数
  4. 关闭通道后,我想执行一些代码。

但是我所缺少的是在所有这些操作完成之后如何执行代码。(在此示例中,是简单的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 确保在codeandbox上打开控制台

在此示例中,我尝试了一些操作,例如使用yield all(workers)yield join(workers)。这些只是使console.log('ALL DONE')工作的尝试。

问题:要对其进行修改,我必须对脚本进行哪些修改?

1 个答案:

答案 0 :(得分:1)

更新:为了使其正常工作,我们需要在put将工作人员完成的工作之后关闭渠道:

numbersQueue.close();

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

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

创建一个效果描述,指示中间件执行以下操作:   并行运行多个效果,并等待它们全部完成。   这完全是标准Promise#all的相应API。

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

enter image description here