javascript - Redux-saga:[...effects] 已被弃用,取而代之的是 all([...effects]),请更新您的代码

标签 javascript reactjs redux-saga

我已经将 redux-saga 升级到了最新的 0.15.x 版本,并且我已经解决了许多关于 [...effects] 的弃用问题,已被弃用,取而代之的是 all([.. .effects]),请更新您的代码

只剩下一个弃用,我已经在这部分代码中识别了它。谁能看一下下面的代码并指出它是如何触发弃用的?

我已尝试按照 https://github.com/redux-saga/redux-saga/releases/tag/v0.15.0 中的说明进行操作变更日志:

alleffect - 并行效果的显式效果,这正是我们通过接受生成的数组所支持的,因此后者现在已被弃用,以支持这种显式性,它很好地映射到 Promise.all API。请从现在开始使用它

这是相关代码:

import { call, put, race, take, takeEvery } from 'redux-saga/effects';
import {
  BATCH_START,
  BATCH_SUCCESS,
  BATCH_FAIL,
  SUB_BATCH_START,
  SUB_BATCH_SUCCESS,
  SUB_BATCH_FAIL
} from 'redux/modules/batch/constants';

/*
  This method is required to prevent additional takes.
*/
export function* takeFirstOccurrence(fn) {
  const res = yield take(fn);
  return res;
}

export const takeSuccess = (c) => (b) => b.type === `${c.type}_SUCCESS` && b.batchId === c.batchId;
export const takeFail = (c) => (b) => b.type === `${c.type}_FAIL` && b.batchId === c.batchId;

export function* batchRequest(action, results = {}) {
  const { batchId, actions } = action;
  try {
    const racer = {};
    const takes = [];
    const keysToSuccess = [];

    // Actions must be array
    for (let i = 0; i < actions.length; i++) {
      let c = actions[i];

      if (Array.isArray(c)) {
        const currentBatchId = `${batchId}.${i}`;
        yield put({ type: SUB_BATCH_START, batchId: currentBatchId });
        const res = yield call(batchRequest, { actions: c, batchId: currentBatchId }, results);
        // if the subbatch return object has an error property then everything has gone to shit. Fail the batch/sub-batch. Pass the object up the chain, so the fail reaches the root batch
        if (res.error) {
          results = {
            ...results,
            error: res.error
          };
          // An error has occurred, so hop out of the loop so the parent batch can fail immediately
          // ...or not, for now, since later batches may contain required error logic.
          // i = actions.length;
        } else {
          // update results such that the next array to be called with call(batchRequest...) gets the new results to pass to it's child actions.
          results = {
            ...results,
            ...res
          };
        }
      } else {
        // The batcher expects an object for each action, with one key, the name to associate with the success or error of the action
        const key = Object.keys(c)[0];
        c = c[key];
        // The single property can be either an action object, or a function that returns an action object. If it is a function, it is passed the current results object
        if (typeof c === 'function') {
          c = c(results);
        }
        if (c) {
          c.batchId = `${batchId}.${key}`;
          if (/.*_REQUEST$/.test(c.type)) {
            racer[key] = take(takeFail(c));
            takes.push(takeFirstOccurrence(takeSuccess(c)));
            keysToSuccess.push(key);
          }
          if (c.type) yield put(c);
        }
      }
    }
    // if the "takes" array has no entries then, by definition, the requests are all synchronous and must succeed. There is no return data, so send empty obj with empty success key
    let returnObj = {};
    // if "takes" has entries then the batch/sub-batch contains at least 1 asynchronous action
    if (takes.length > 0) {
      const { success, ...errors } = yield race({
        success: takes,
        ...racer
      });
      // if any of the errors wins the race, then the success property is undefined. Return obj with error property, it will fail the batch/sub-batch.
      if (!success) {
        returnObj = { error: errors };
      } else {
        // else transfer the success array into an object, mapping them in order to the keysToSuccess array constructed eariler
        const successAsKeys = {};
        success.forEach((s, i) => {
          successAsKeys[keysToSuccess[i]] = s;
        });
        returnObj = successAsKeys;
      }
    }
    results = {
      ...results,
      ...returnObj
    };
    // either we reach this point because there are no takes and the batch must succeed, or we exited a loop of arrays, and need to check if there is an error on the results added during that
    if (results.error) {
      yield put({ type: batchId.indexOf('.') === -1 ? BATCH_FAIL : SUB_BATCH_FAIL, batchId, data: results });
    } else {
      yield put({ type: batchId.indexOf('.') === -1 ? BATCH_SUCCESS : SUB_BATCH_SUCCESS, batchId, data: results });
    }
    return results;
  } catch (error) {
    console.log(error);
  }
}

export default function batchListener() {
  return function* actionListener() {
    return yield takeEvery(action => action.type === BATCH_START && action.batchId, batchRequest);
  };
}

最佳答案

我认为你的这部分代码可能就在它后面:

const { success, ...errors } = yield race({
    success: takes,
    ...racer
});

takes 这里是一个数组。尝试一下 all(takes) 修复它。

关于javascript - Redux-saga:[...effects] 已被弃用,取而代之的是 all([...effects]),请更新您的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45457371/

相关文章:

javascript - 用星号替换数字 javascript/jquery?

javascript - 无法在 useEffect 中模拟函数

redux-saga - 使用多个 API 调用进行 Redux saga 错误处理

javascript - 如何使用 redux saga 从 redux store 获取商品

按钮单击事件上的 JavaScript 函数在 WaveMaker 中不起作用

javascript - RxJS 1 array item into sequence of single items - 运算符

reactjs - 如何在 TypeScript 中安装/导入 React

javascript - 从数组 React 中过滤过期的卡片

react-native - React Native redux saga 产量不适用于第一个操作

javascript - 如何为 javascript 排序函数制作一个有效的比较器来对字符串数组进行排序?