映射 Axios 响应并将第二个 Axios 响应附加到第一个
Map over Axios Response and append 2nd Axios Response to 1st
我正在使用 axios
和 TMDb API 创建电影搜索 React 应用程序。我想进行 axios.get
调用以根据 query
搜索电影,然后映射响应,并将每部电影的 movie.id
传递到第二个 axios
调用获取每部电影的更多详细信息。
我尝试了很多方法,但我对如何 return 这些值感到困惑,或者我是否需要在代码中的某个时刻使用 async/await 来等待响应.我真的不知道解决这个问题的最佳方法 - 必须有一个简单的方法来按顺序进行,但问题的异步性质使我很难做到这一点。
我认为在我的搜索函数中进行第一个 axios 调用会更简单,然后编写第二个函数 getDetails(id)
获取电影 ID 并使用它进行 axios 调用。
理想情况下,如果我在地图中调用 getDetails 函数,获得响应,将该响应附加到我的电影数组,我可以轻松地拥有一个电影数组,每个电影都附加了详细信息。然后我可以将整个数组存储在状态中,并使用单个状态来管理我所有的电影数据。我知道这个过程不是同步的,而且 axios 是基于承诺的,但是有没有办法按顺序处理这个问题,或者我是不是完全错了?我知道 .push()
在这种情况下不起作用,但我尝试了其他方法,它们总是 return 未定义、承诺或意外结果。
const search = query => {
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
)
.then(response => {
response.data.results.map(movie => {
const details = getDetails(movie.id);
return movie.push(details);
});
});
};
const getDetails = id => {
axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${API_KEY}&language=en-US`
)
.then(response => {
return response.data;
});
};
编辑 1: 我玩过 Abanoub Istfanous 的答案,它似乎 return undefined 添加了调度来更新我的状态。我对其进行了更多调整,第二组标记为 WORKING 的代码似乎正在显示一些搜索结果,但我无法将 getDetails
中的任何附加数据呈现到屏幕上,因为它们显示为未定义。我还是做错了什么吗?
不工作:
const search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: data
});
return data;
};
// getDetails is unchanged...
正在工作:
const search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: response.data.results
});
return data;
};
// getDetails is unchanged...
我推荐使用 Promise
/*
*@return data
*/
const getDetails = async (id) => {
const response = await axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${API_KEY}&language=en-US`
)
return response.data
};
然后
const search = async (query) => {
const response = await axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
}))
return data
};
之所以 return 未定义是因为 Promise.all() 将在作业队列上异步执行,并且最终只会 return 结果 Javascript被执行并且调用堆栈变空。因此,您的代码的一个简单解决方案是在 Promise.all().
之前放置一个 await
const search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = await Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: response.data.results
});
return data; //No need to return data since you are dispatching it to redux store
};
您可以在此处阅读有关 JS 在浏览器上的异步特性的更多信息:
我正在使用 axios
和 TMDb API 创建电影搜索 React 应用程序。我想进行 axios.get
调用以根据 query
搜索电影,然后映射响应,并将每部电影的 movie.id
传递到第二个 axios
调用获取每部电影的更多详细信息。
我尝试了很多方法,但我对如何 return 这些值感到困惑,或者我是否需要在代码中的某个时刻使用 async/await 来等待响应.我真的不知道解决这个问题的最佳方法 - 必须有一个简单的方法来按顺序进行,但问题的异步性质使我很难做到这一点。
我认为在我的搜索函数中进行第一个 axios 调用会更简单,然后编写第二个函数 getDetails(id)
获取电影 ID 并使用它进行 axios 调用。
理想情况下,如果我在地图中调用 getDetails 函数,获得响应,将该响应附加到我的电影数组,我可以轻松地拥有一个电影数组,每个电影都附加了详细信息。然后我可以将整个数组存储在状态中,并使用单个状态来管理我所有的电影数据。我知道这个过程不是同步的,而且 axios 是基于承诺的,但是有没有办法按顺序处理这个问题,或者我是不是完全错了?我知道 .push()
在这种情况下不起作用,但我尝试了其他方法,它们总是 return 未定义、承诺或意外结果。
const search = query => {
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
)
.then(response => {
response.data.results.map(movie => {
const details = getDetails(movie.id);
return movie.push(details);
});
});
};
const getDetails = id => {
axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${API_KEY}&language=en-US`
)
.then(response => {
return response.data;
});
};
编辑 1: 我玩过 Abanoub Istfanous 的答案,它似乎 return undefined 添加了调度来更新我的状态。我对其进行了更多调整,第二组标记为 WORKING 的代码似乎正在显示一些搜索结果,但我无法将 getDetails
中的任何附加数据呈现到屏幕上,因为它们显示为未定义。我还是做错了什么吗?
不工作:
const search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: data
});
return data;
};
// getDetails is unchanged...
正在工作:
const search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: response.data.results
});
return data;
};
// getDetails is unchanged...
我推荐使用 Promise
/*
*@return data
*/
const getDetails = async (id) => {
const response = await axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${API_KEY}&language=en-US`
)
return response.data
};
然后
const search = async (query) => {
const response = await axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = Promise.all(response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
}))
return data
};
之所以 return 未定义是因为 Promise.all() 将在作业队列上异步执行,并且最终只会 return 结果 Javascript被执行并且调用堆栈变空。因此,您的代码的一个简单解决方案是在 Promise.all().
之前放置一个 awaitconst search = async query => {
dispatch({
type: MOVIE_SEARCH_REQUEST
});
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`
);
const data = await Promise.all(
response.data.results.map(async movie => {
movie.details = await getDetails(movie.id);
})
);
dispatch({
type: MOVIE_SEARCH_COMPLETE,
payload: response.data.results
});
return data; //No need to return data since you are dispatching it to redux store
};
您可以在此处阅读有关 JS 在浏览器上的异步特性的更多信息: