首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Redux-saga:[...effects]已被所有([...effects])否决,请更新您的代码。

Redux-saga:[...effects]已被所有([...effects])否决,请更新您的代码。
EN

Stack Overflow用户
提问于 2017-08-02 09:49:49
回答 1查看 2.9K关注 0票数 2

我已经将redux-saga升级到了最新的0.15.x版本,并且我已经从[...effects] has been deprecated in favor of all([...effects]), please update your code的角度解决了很多不推荐的问题。

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

我尝试遵循https://github.com/redux-saga/redux-saga/releases/tag/v0.15.0变更列表中的说明:

all effect - explicit effect for parallel effects, which is exactly what we had been supporting by accepting yielded arrays, so the latter is become deprecated now in favor of this explicitness which nicely maps to the Promise.all API. Please use this from now on

以下是有关守则:

代码语言:javascript
复制
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);
  };
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-02 12:28:02

我认为您的代码的这一部分可能是背后的原因:

代码语言:javascript
复制
const { success, ...errors } = yield race({
    success: takes,
    ...racer
});

takes这里是一个数组。如果all(takes)修复了它,试一试。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45457371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档