【问题标题】:how to handle async actions correctly?如何正确处理异步操作?
【发布时间】:2016-07-12 20:52:06
【问题描述】:

我有一个异步操作

function fetch(url) {
  dispatch => {
    request(url).then(
      resp => dispatch({type: FETCH_SUCCESS, resp}),
      error => dispatch({type: FETCH_FALUIRE, error})
  );

} }

UI 有一个页面来列出所有项目,当单击其中一个时,它会调度一个带有该项目 url 的操作。

当我先点击item1时,如果item2的响应早于item1,我会快速点击item2。 store中item2的数据会被item1覆盖。

fetch('http://remote/items/item1'); //first
fetch('http://remote/items/item2'); // then

如何忽略 item1 的结果?或者我怎样才能让项目的调度总是在 item1 之后触发

我能想到的是,在发送请求之前调度 url。

function fetch(url) {
  dispatch => {
    dispatch({type: FETCH_START, url});
    request(url).then(
      resp => dispatch({type: FETCH_SUCCESS, resp, url}),
      error => dispatch({type: FETCH_FALUIRE, error, url})
    );
  }
}

在 reducer 中,我检查 url 以决定是否应该忽略响应。

function reduceFetch(state = initialState, action) {
  switch(action.type) {
    case FETCH_START:
      return {initialState, action.url};
    case FETCH_SUCCESS:
      if (state.uri === action.url) {
        return {state, resp: action.resp};
      } else {
        return state;
      }
    ...
  }

}

感谢您的帮助!

【问题讨论】:

    标签: redux


    【解决方案1】:

    您的解决方案应该有效。至少如果你忽略一些疯狂的事情,比如

    1. 请求项目 1
    2. 请求项目2
    3. 再次请求 item1。
    4. 第三个请求正在返回。
    5. 第一个请求失败。或者第一个请求正在返回,并且 item1 在请求之间发生了更改。

    或者,您可以让您的 fetch 函数仅在最近一次调用时调度事件。

    const fetchLatest = (called => url => {
      const snapshot = ++called
    
      return dispatch => request(url).then(
        resp => snapshot === called && dispatch(...),
        error => snapshot === called && dispatch(...)
      )
    })(0)
    

    【讨论】:

    • 谢谢Tarabanko,这是我的想法,但不知道如何实现。
    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 2015-11-22
    • 2023-02-08
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多