【问题标题】:React Redux with SAGA - Create a queue of the same action使用 SAGA 反应 Redux - 创建相同操作的队列
【发布时间】:2021-04-15 08:11:14
【问题描述】:

我有一个应用程序,它每次检索包含axios 50 个项目的数据并将它们分页。最初我进行双重调用,第一个准备当前页面(25 项),第二个准备下一页(25 项)。

然后用户每次点击下一页,都会调用其他50个item,以此类推。

因此,该应用“在后台”检索数据并准备下一页以获得更好的用户体验。

我的问题是,我如何使用SAGA 创建一个呼叫队列?

如果用户多次点击下一页我有一个“拥塞”的呼叫,可能(已经测试)第三次完成后第四次完成,那么数据不按顺序。

我想要的是这样的:

1 call => end =>
2 call => end =>
3 call => end =>
4 call => end =>

等等……

我使用的函数是setSpotifyData()

这是我的代码:

// first call just for the token and when the token expires

function* getSpotifyData(obj) {
  try {
    yield put({
      type: "GET_SPOTIFY_USER_DATA_SUCCESS",
      payload: obj.payload,
    });
  } catch (error) {
    yield put({ type: "GET_SPOTIFY_USER_DATA_ERROR", payload: error });
  }
}

// 我想“排队”的函数:

function* setSpotifyData(obj) {
  const url = "http://localhost:8888/api/spotifyuserdata";

  // route the needs auth
  const config = {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${obj.payload.token}`,
    },
    // becomes query in the route
    params: obj.payload,
    url: url,
    transformResponse: [
      (data) => {
        return data;
      },
    ],
  };

  try {
    const spotifyData = yield axios(config);
    /**
     * @description Remapping to make it lighter
     */

    ...code...

    yield put({
      type: "SET_SPOTIFY_USER_DATA_SUCCESS",
      payload: newAlbumsArr,
    });
    return newAlbumsArr;
  } catch (error) {
    yield put({ type: "SET_SPOTIFY_USER_DATA_ERROR", payload: error });
  } finally {
    yield put({ type: "SET_SPOTIFY_USER_DATA_END" });
  }
}

function* watchAllSpotifyUserDataSaga() {
  yield takeEvery("GET_SPOTIFY_USER_DATA", getSpotifyData);
  yield takeEvery("SET_SPOTIFY_USER_DATA", setSpotifyData);
}

export default watchAllSpotifyUserDataSaga;

我已经尝试过 SAGA 的throttle。但实际上并没有改变。

我也想禁用加载按钮,但我想学习新的东西。

提前致谢

【问题讨论】:

    标签: reactjs redux redux-saga


    【解决方案1】:

    您正在使用 takeEvery 帮助器,它接受所有 GET_SPOTIFY_USER_DATA 操作并调用 getSpotifyData 但问题是它允许 多个 getSpotifyData 实例被同时调用。换句话说,您可能会在之前的任务尚未终止时开始新任务,这就是您的数据可能以错误的顺序出现的原因。

    您可以使用 actionChannel 效果,根据文档,该效果会生成一个动作队列并逐个执行。这意味着我们在处理上一个动作时采取下一个动作。

    为此,您需要在 getSpotifyData 函数中创建一个频道

    function* getSpotifyData(obj) {
      const usersChannel = yield actionChannel('GET_SPOTIFY_USER_DATA')
    
      while (true) {
       try {
        const {payload} = yield take(usersChannel)
    
        yield call(setSpotifyData, payload)
      } catch (error) {
        console.error('some error:', error)
      }
    }
    

    如果需要,您需要将通过 put 发送到 store 的 getSpotiFyData 中的操作移至您的工作人员 saga,即 setSpitiFyData。

    您的传奇手表AllSpotifyUserDataSaga 现在也需要修改。

    你可以改写如下:

    export default function* watchAllSpotifyUserDataSaga() {
      yield all([
        getSpotiFyData(),
        //some other sagas but I don't think you need to include setSpotifyData here
        //as it's called from the other saga
      ])
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-04
      • 1970-01-01
      相关资源
      最近更新 更多