【问题标题】:redux saga multiple calls make next one when the other failsredux saga 多个调用在另一个失败时进行下一个
【发布时间】:2021-09-09 11:33:10
【问题描述】:

我有一个传奇在其中多次调用:

function* membersInfoSaga({ payload }) {
    const endpoints = [
        api.fetchNotifications,
        api.fetchPosts,
        api.fetchMessages,
        api.fetchActivities
    ]

    const responses = yield all(endpoints.map(endpoint => {
        try {
            return call(endpoint, payload.memberId, payload.page, payload.pageSize)
        } catch (error) {
            return { data: {} }
        }
    }))

当一个呼叫得到 400 作为响应时,我希望它为其他呼叫继续,并为失败的呼叫返回 { data: {} }

我正在使用 Fetch API 进行调用。这是我的 api.js:

function callApi(endpoint, options, unauthorized, isRefreshToken) {
    const URL = BASE_URL + endpoint
    const ACCESS_TOKEN = localStorage.getItem("access_token")
    if (!options) options = {}

    options["headers"] = {
        "Content-Type": "application/json",
        "Accept": "application/json"
    }

    if (!unauthorized) {
        options.headers["Authorization"] = `Bearer ${ACCESS_TOKEN}`
    }

    return fetch(URL, options)
        .then((response) => response.json())
        .then((response) => {
            if (response.code >= 200 && response.code <= 299) {
                return Promise.resolve(response)
            } else if (response.code === 401) {
                if (isRefreshToken) {
                    store.dispatch({ type: actionTypes.AUTH_REFRESH_FAILED })
                } else {
                    store.dispatch({
                        type: actionTypes.INVALID_TOKEN,
                        payload: { error: response.error.message }
                    })

                    return { error: response.error.message }
                }
            } else {
                return Promise.reject(response.error.message)
            }
        })
        .catch((error) => {
            return Promise.reject(error)
        })
}

这是我在 saga 调用方法中调用的函数:

const fetchNotifications = (memberId, page, pageSize) => callApi(`notifications/${memberId}?page=${page}&page_size=${pageSize}`)

【问题讨论】:

    标签: javascript reactjs fetch-api redux-saga


    【解决方案1】:

    您的代码中的问题是try..catch 是您调用call 效果创建者的位置,而不是您生成结果效果对象的位置。当然,您也不能直接在箭头函数内屈服。解决这个问题的方法是将try..catch 包装在额外的saga 生成器中,然后由all 效果执行。

      const responses = yield all(
        endpoints.map((endpoint) => {
          return call(function* () {
            try {
              return yield call(endpoint, payload.memberId, payload.page, payload.pageSize);
            } catch (error) {
              return { data: {} };
            }
          });
        })
      );
    

    【讨论】:

      【解决方案2】:

      我已经解决了这个问题。我已经对我的传奇进行了一些更新,现在我可以拨打多个电话,即使其中一些电话返回 400 作为响应。这是我的解决方案:

      function* fetchMembersInfo(payload) {
          yield fork(membersNotificationsSaga, { payload })
          yield fork(membersPostsSaga, { payload })
          yield fork(membersMessagesSaga, { payload })
          yield fork(membersActivitesSaga, { payload })
      }
      
      const getNotifications = state => state.members.selectedAccount.notifications.data.notifications
      const getPosts = state => state.members.selectedAccount.posts.data.posts
      const getMessages = state => state.members.selectedAccount.messages.data.messages
      const getActvities = state => state.members.selectedAccount.activites.data.activities
      
      function* membersInfoSaga({ payload }) {
          try {
              yield call(fetchMembersInfo, payload)
      
              const notifications = yield select(getNotifications)
              const posts = yield select(getPosts)
              const messages = yield select(getMessages)
              const activites = yield select(getActivities)
              ...
          } catch (error) {
              ...
          }
      }
      

      【讨论】:

      猜你喜欢
      • 2018-12-13
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 2017-11-13
      • 1970-01-01
      • 2019-09-14
      • 2022-01-12
      相关资源
      最近更新 更多