我正在尝试执行多个异步操作:Axios请求位于for循环内。一切解决后,我想做点什么,但事情太多了,我不知道该怎么做。
我考虑过让Sourcer函数异步并在每次迭代中等待它(并将for循环包装在async函数中),但是一个问题是sourcer实际上不返回任何东西。我不知道如何从Axios的“ finally”子句中的sourcer返回。另一个问题是,我不想等待每个源程序调用,因为这会影响性能。
Promise。听起来似乎是正确的方向,但我不知道如何使用此for循环来实现它。
这是我的代码的相关部分(ts是一大堆对象):
.then(ts => {
// Create an association object that determines each media item's source
const sourcer = media => { // Input is either [image filename, image url] or [image filename, image url, video filename, video url]
// Test to see if the original URL works
let validURL = true
axios.get(media[1])
.then(resp => {
if (resp.status.toString()[0] !== '2') validURL = false
})
.catch(resp => {
if (resp.status.toString()[0] !== '2') validURL = false
})
.finally(() => {
let newSources = JSON.parse(JSON.stringify(this.state.sources))
let newModals = JSON.parse(JSON.stringify(this.state.modals))
if (validURL) newSources[media[0]] = media[1]
// If the original URL does not work, pull media item from server
else newSources[media[0]] = `http://serveripaddress/get_media?filename=${media[0]}`
newModals[media[0]] = false
this.setState({ sources: newSources, modals: newModals })
})
if (media.length > 2) { // If the media item is a video, do the same checks
let validVURL = true
axios.get(media[3])
.then(resp => {
if (resp.status.toString()[0] !== '2') validVURL = false
})
.catch(resp => {
if (resp.status.toString()[0] !== '2') validVURL = false
})
.finally(() => {
let newSources2 = JSON.parse(JSON.stringify(this.state.sources))
let newThumbnails = JSON.parse(JSON.stringify(this.state.thumbnails))
if (validVURL) newSources2[media[2]] = media[3]
else newSources2[media[2]] = `http://serveripaddress/get_media?filename=${media[2]}`
newThumbnails[media[0]] = media[2] // Add an association for the video and its thumbnail
this.setState({ sources: newSources2, thumbnails: newThumbnails })
})
}
}
for (let t of ts) {
if (t.media) for (let m of t.media) sourcer(m)
if (t.preview_media) sourcer(t.preview_media)
if (t.video) sourcer(t.video)
}
})
我想在遍历ts并且完成所有源程序调用之后做些事情。
我不是想找人为我编写代码,但是朝着正确的方向微移将不胜感激。
答案 0 :(得分:1)
axios.get
将返回一个Promise
,因此只需建立Promise
数组并使用Promise.all
因此,就您而言,不必执行http调用并等待响应,只需将其添加到您的数组中即可。
类似的事情会起作用。我删除了处理每个get
请求的响应的代码。您可以将该代码合并(或仅复制/粘贴)到我在下面放置占位符的位置:
.then(ts => {
// Create an association object that determines each media item's source
const sourcer = media => { // Input is either [image filename, image url] or [image filename, image url, video filename, video url]
// Test to see if the original URL works
let validURL = true;
const promises = [];
promises.push(axios.get(media[1]));
if (media.length > 2) { // If the media item is a video, do the same checks
let validVURL = true;
promises.push(axios.get(media[3]));
}
}
for (let t of ts) {
if (t.media)
for (let m of t.media) sourcer(m)
if (t.preview_media) sourcer(t.preview_media)
if (t.video) sourcer(t.video)
}
// Execute the Promises
Promise.all(promises).then( results => {
const media1 = results[0];
const media3 = results[1];
// TODO: Run your code for media1/media3 results
})
})