Reactjs 如何在一个循环中实现多个承诺
我正在尝试使用flicker getinfo请求按标题或描述过滤图像,该请求返回此信息 我试图做的是为当前图像数组中的每个图像发送一个getinfo请求,查看标题或描述是否与用户输入匹配,如果匹配,则呈现这个新的过滤图像数组 我无法解决如何调用每个图像,只有在循环结束并完成过滤数组后,才能对该数组调用setStateReactjs 如何在一个循环中实现多个承诺,reactjs,promise,axios,Reactjs,Promise,Axios,我正在尝试使用flicker getinfo请求按标题或描述过滤图像,该请求返回此信息 我试图做的是为当前图像数组中的每个图像发送一个getinfo请求,查看标题或描述是否与用户输入匹配,如果匹配,则呈现这个新的过滤图像数组 我无法解决如何调用每个图像,只有在循环结束并完成过滤数组后,才能对该数组调用setState filterImages = (filter) =>{ if(filter.length === 0) return; const cur
filterImages = (filter) =>{
if(filter.length === 0)
return;
const currentImages = this.state.images;
console.log(currentImages[0]);
const newFilterdImages =[];
const baseUrl = 'https://api.flickr.com/';
for (const img of currentImages){
axios({
url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
baseURL: baseUrl,
method: 'GET'
})
.then(res=> res.data)
.then(res=> {
if( res && res.photo) {
const imageInfo = res.photo;
//console.log(imageInfo.title._content,imageInfo.description._content);
if(imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter)){
newFilterdImages.push(img);
}
}
}).then( res => console.log("first then " + newFilterdImages)) // output the newFilterdImages array on each call
}
this.setState({images:newFilterdImages}) // this will not work
}
如何等待此循环结束,然后才使用新的筛选器映像更改当前数组?您需要使用
Promise.all()
等待所有映像解析,然后再对其进行筛选并分配到状态
filterImages = (filter) =>{
if(filter.length === 0)
return;
const currentImages = this.state.images;
console.log(currentImages[0]);
const newFilterdImages =[];
const baseUrl = 'https://api.flickr.com/';
const promises = [];
for (const img of currentImages){
promises.push(axios({
url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
baseURL: baseUrl,
method: 'GET'
})
.then(res=> res.data)
}
Promise.all(promises).then((data) => {
data.forEach((item, index) => {
if( item && item.photo) {
const imageInfo = res.photo;
if(imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter)){
newFilterdImages.push(currentImages[index]);
}
}
});
this.setState({images:newFilterdImages})
})
}
您需要使用
Promise.all()
等待所有图像解析,然后再过滤它们并分配给状态
filterImages = (filter) =>{
if(filter.length === 0)
return;
const currentImages = this.state.images;
console.log(currentImages[0]);
const newFilterdImages =[];
const baseUrl = 'https://api.flickr.com/';
const promises = [];
for (const img of currentImages){
promises.push(axios({
url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
baseURL: baseUrl,
method: 'GET'
})
.then(res=> res.data)
}
Promise.all(promises).then((data) => {
data.forEach((item, index) => {
if( item && item.photo) {
const imageInfo = res.photo;
if(imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter)){
newFilterdImages.push(currentImages[index]);
}
}
});
this.setState({images:newFilterdImages})
})
}
在Javascript中,承诺表示可能缓慢操作的未来结果。实现承诺的结果需要在其上运行
。然后()
为了更方便地等待未来的结果,我们为您提供了方法Promise.all()
。它获取承诺列表并返回一个承诺,该承诺与所有提供的承诺的未来值进行解析
结合这些要点,我们可以通过将图像列表映射到承诺列表,在所有图像上运行axios
:
let axioses = currentImages.map((img) => {
return axios({
url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
baseURL: baseUrl,
method: 'GET'
})
})
…然后在结果列表上运行Promise.all()
,并将其视为一个Promise,当所有结果都可用时,它将与来自axios()
的结果列表进行解析:
Promise.all(axioses).then((results) => {
const filteredResults = results.filter((res) => {
if (!res || !res.photo) {
return false
}
const imageInfo = res.photo;
return imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter))
)
this.setState({ images: filteredResults.map(res => res.photo) })
})
在Javascript中,承诺表示可能缓慢操作的未来结果。实现承诺的结果需要在其上运行。然后()
为了更方便地等待未来的结果,我们为您提供了方法Promise.all()
。它获取承诺列表并返回一个承诺,该承诺与所有提供的承诺的未来值进行解析
结合这些要点,我们可以通过将图像列表映射到承诺列表,在所有图像上运行axios
:
let axioses = currentImages.map((img) => {
return axios({
url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
baseURL: baseUrl,
method: 'GET'
})
})
…然后在结果列表上运行Promise.all()
,并将其视为一个Promise,当所有结果都可用时,它将与来自axios()
的结果列表进行解析:
Promise.all(axioses).then((results) => {
const filteredResults = results.filter((res) => {
if (!res || !res.photo) {
return false
}
const imageInfo = res.photo;
return imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter))
)
this.setState({ images: filteredResults.map(res => res.photo) })
})
您正在混合异步和同步代码。承诺是异步的,这样做newFilterdImages.push(img)
将在this.setState({images:newFilterdImages})之后执行。
您正在混合异步和同步代码。承诺是异步的,这样做newFilterdImages.push(img)
将在this.setState({images:newFilterdImages})
newFilterdImages.push(img)之后执行
->img未定义
您需要获取索引数据。forEach((项,索引){…
然后在数组中推送相应的图像newFilterdImages.push(currentImages[index]);
@OlivierBoissé谢谢您的评论。我更新了我的答案,没有注意newFilterdImages.push(img)
->img未定义
您需要获取索引数据。forEach((项,索引){…
然后在数组中推送相应的图像newfilterImages.push(currentImages[index]);
@OlivierBoissé谢谢您的评论。我更新了答案,没有注意到这一点