首页 > 解决方案 > Redux saga 从 saga-action 内部的 map 调度动作

问题描述

我通过以下方式调用 API:

  1. 调用 main api,它给了我一个对象数组。
  2. 对于数组中的每个对象,我必须异步调用另一个 API。
  3. 一旦对象的子 API 调用完成,更新它在 redux 存储中的数据,它是一个数组 (ofc) 并显示它。

所以这个场景是一个列表,显示以动态方式增长的项目。

由于我使用的是 redux-saga,所以我必须从 redux-action 内部调度第二部分。我尝试了以下方式:

const response = yield call(get, 'endpoint')

const configHome = response.map(function* (ele) {
    const data = yield call(get, ele.SomeURI + '?someParameter=' + ele.someObject.id)
}))

这不起作用,因为 map 对生成器函数一无所知。所以我尝试了这个:

const response = yield call(get, 'endpoint')

const configHome = yield all(response.map((ele) => {

     return call(get, paramsBuilder(undefined, ele.CategoryID))

}))

但这将阻止我的 UI 显示可用数据,直到所有子 API 调用完成。

我也尝试过创建一个单独的生成器函数,我从 map 内部调用它并调用它的 .next() 函数,但这里的问题再次是 saga 不控制该生成器函数,因此调用效果不会正确返回任何值。

完全卡在这部分。将不胜感激任何帮助。

标签: reactjsreduxredux-saga

解决方案


yield all- 生成器被阻塞,直到所有效果都被解决或一旦被拒绝

因此,您需要为每个子 API 分别调度事件

假设您有 2 个操作:

export const getMainApi =() => ({
  type: types.GET_MAIN_API,
});

export const getSubApi = endpoint => ({
  type: types.GET_SUB_API,
  endpoint,
});

那么您的操作将是:

const get = endpoint => fetch(endpoint).then(response => response);

function* fetchMainApi(action) {
  try {
    const response = yield call(get, 'endpoint');
    for (let i = 0; i < response.length; i += 1) {
      // dispatch here all sub APIs
      yield put(
        getSubApi(
          response[i].SomeURI + '?someParameter=' + response[i].someObject.id,
        ),
      );
    }
  } catch (e) {
    console.log(e);
  }
}

function* fetchSubApi(action) {
  try {
    const response = yield call(get, action.endpoint);
    yield put({
      type: types.RECEIVE_SUB_API,
      response
    });
  } catch (e) {
    console.log(e);
  }
}

takeLatest(type.GET_MAIN_API, fetchMainApi)
takeEvery(types.GET_SUB_API, fetchSubApi)

因此,在成功接收子 API 时,您需要将数据插入到减速器内的状态中。

这只是伪代码。


推荐阅读