在Redux-Saga中启动新延迟时如何清除先前的延迟效果

时间:2019-04-25 11:03:22

标签: reactjs redux-saga

我有一个包含通知逻辑的工作传奇。如果响应正常-我将成功信息的数据推送到我的商店,然后在“ NotifyMessage”全局组件内呈现适当的消息。我从商店收到的所有消息和消息类型。如果响应不正确,我也会做同样的事情。在每次错误/成功请求之后,我都会使用适当的信息将操作推送到我的商店。我使用延迟效果,等待三秒钟,三秒钟后,我将操作推送到商店以隐藏通知消息。

问题是,当我尝试过快提出一个请求时,仍然有延迟效果。似乎一条消息我可以看到2秒钟,而另一条消息可以看到1秒钟(仍然有以前的延迟效果在起作用)。启动新的时,如何取消/清除redux saga生成器函数中的先前延迟效果(如setTimeout中的clearTimeout)?

我的sagas模式如下:

//Somewhere inside component:
<NotifyMessage alignText="center" type={notifyMsgType}>
     {notifyMsg}
</NotifyMessage>

//Store connection inside component
export default connect(
  ({ notify }) => ({
    notifyMsg: notify.message,
    notifyMsgType: notify.type,
 }),

import {
  CREATE_ITEM_FILTER,
  DELETE_ITEM_FILTER,
}
  from '../../components/manageFilters/actions';

import { createItemFilter } from './manageFilters/createItemFilter';
import { deleteItemFilter } from './manageFilters/deleteItemFilter';

export default function* root() { 
 yield takeEvery(CREATE_ITEM_FILTER, createItemFilter);
 yield takeEvery(DELETE_ITEM_FILTER, deleteItemFilter);
 and so on...
}


function* createItemFilter(action) {
try {
  if (response.ok) {
      const data = yield response.json();
      yield put(createItemFilterSuccess(data));
      //Update store with appropriate message and type
      yield put(showNotifyMessage([`Country ${country} was added to ${region} 
      region successfully`, 'success']));
      //Start timer
      yield delay(3000);
      //Hide notify message (clear 'message' and 'type' keys in store)
      yield put(hideNotifyMessage());
    }

} catch (e) {
    yield put(showNotifyMessage(['Error occurred during making request', 'error']));
    yield delay(3000);
    yield put(hideNotifyMessage());
  }
}

2 个答案:

答案 0 :(得分:0)

它在此沙箱中正常运行(延迟不会阻止其他通知)https://codesandbox.io/s/3q7402mp31

import * as types from './types';
import {
    cancelled,
    takeEvery,
    cancel,
    delay,
    fork,
    take
} from 'redux-saga/effects';
import { toast } from 'react-toastify';

function* notification() {
    let notificationId = null;
    try {
        notificationId = toast(`Notification ⚡`);
        yield delay(3000);
        toast.dismiss(notificationId);
    } catch (e) {
        notificationId = yield toast.error(`Error`);
        yield delay(3000);
        toast.dismiss(notificationId);
    // The part of the saga that is triggered after cancel effect occurs
    } finally {
        if (yield cancelled()) toast.dismiss(notificationId);
    }
}

负责取消中止的通知的通知管理器:

function* notificationManager() {
    const notify = yield fork(notification);
    yield take(types.SHOW_NOTIFICATION);
    yield cancel(notify); // Triggering cancel
}

观看者的传奇

export default function* rootSaga() {
    yield takeEvery(types.SHOW_NOTIFICATION, notificationManager);
}

答案 1 :(得分:0)

我已通过将setTimeout移到“ NotifyMessage”组件本身解决了该问题。从商店收到新邮件时-我清除超时并在3秒后隐藏邮件。它按预期工作。我已经完全消除了我的工人骚扰的延迟影响。我想有一种更好的方法可以仅使用工人sagas(种族效应和setTimeout?)来解决此问题,但是目前,一切都按预期进行。