在一个动作创建者中反应redux multiple请求

时间:2016-08-25 04:21:36

标签: javascript reactjs request redux react-redux

我想连续发出2个请求,有点像瀑布式。我想首先请求一个特定的口袋妖怪,然后根据返回的obj的有效载荷类型,我想要求更多的信息。我认为最好将其分离给几个动作创建者,但感到奇怪fetchPokemon以另一个获取结束。这是最佳做法吗?

export const fetchPokemon = function (pokemonName) {
  return function (dispatch) {
    dispatch(requestPokemon(pokemonName))
    const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`
    return $.ajax({
      url: requestURL,
    }).done(function (data) {
      dispatch(receivePokemon(data))
      fetchPokeTypeInfo(data.types[0].type.url)
    })
  }
}

...

export const fetchPokemonTypeInfo = function (url) {
  return function (dispatch) {
    dispatch(requestPokemonTypeInfo(url))
    return $.ajax({
      url: url,
    }).done(function (data) {
      dispatch(receivePokemonTypeInfo(data))
    })
  }
}

3 个答案:

答案 0 :(得分:1)

我认为打破这两者并没有什么特别的错误。我要问的一个问题是:"我是否会直接调用fetchPokemonTypeInfo(),而不是fetchPokemon()?"。如果没有,那么我只是从第一个.done()函数返回第二个.ajax调用。如果第一个调用始终是dep,那么如果它们只是嵌套,似乎更容易推断出发生了什么。此外,如果您确实希望将它们分开,则需要将调度函数和url传递给第二个函数,否则在fetchPokemonTypeInfo()中未定义调度。

<强>更新

您可以将第二个电话嵌套在第一个电话中,如下所示:

export const fetchPokemon = function (pokemonName) {
    return function (dispatch) {
        dispatch(requestPokemon(pokemonName));
        const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`;
        return $.ajax({
            url: requestURL,
        }).done(function (data) {
            dispatch(receivePokemon(data));
            dispatch(requestPokemonTypeInfo(data.types[0].type.url));

            return $.ajax({
                url: data.types[0].type.url,
            }).done(function (data) {
                dispatch(receivePokemonTypeInfo(data));
            });
        });
    }
}

答案 1 :(得分:1)

有一种方法可以提供清晰且可预测的解决方案。

如果您使用的是redux,则可以使用中间件来进行API调用。此外,在您的中间件中,您可以通过允许接受多个请求(可能在数组中)并在返回成功Promise之前完全解决它们来扩展其功能。

点击此链接以供参考: https://github.com/reactjs/redux/blob/master/examples/real-world/middleware/api.js

这是一个功能中间件,但你必须扩展它以支持多个请求:)祝你好运!

答案 2 :(得分:1)

使用redux-saga https://github.com/yelouafi/redux-saga

注意:以下代码只是一个概念,您需要根据需要进行调整。

function* fetchPokemon(action) {
   try {
      //fetch1
      const pokemon = yield call(Api.fetchPokemon, action.payload.pokemonId);
      //this action will execute only after fetch1 is successful
      yield put({type: "FETCH_POKEMON_SUCCEEDED", payload: pokemon});
      //fetch2
      const pokemonInfo = yield call(Api.fetchPokemonInfo, types[0].type.url)
      // execute after fetch2 is successful 
      yield put({type: "FETCH_POKEMON_INFO_SUCCEEDED", payload: pokemonInfo})
   } catch (e) {
      yield put({type: "FETCH_FAILED", message: e.message});
   }
}

// wait for an action and fire a saga
function* watchFetchPokemonRequest() {
  yield* take("FETCH_POKEMON_REQUESTED", fetchPokemon);
}

Sagas使用Generators,它可以“同步”异步代码。这样你就不需要在promises等中处理回调。这是描述应用程序副作用的一种很好而且干净的方式。