我想连续发出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))
})
}
}
答案 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等中处理回调。这是描述应用程序副作用的一种很好而且干净的方式。