我有一个像这样的数组
let array =[ {message:'hello'}, {message:'http://about.com'}, {message:'http://facebook.com'}]
我想循环遍历它,在每个项目中,我向服务器发出请求以获取打开的图形数据,然后将获取的数据保存回数组。预期结果
array =[
{message:'hello'},
{message: {
url:'http://about.com', title:'about'
}
},
{message:{
url:'http://facebook.com', title:'facebook'
}
}
]
我需要在异步完全完成后执行其他操作。下面的代码是我认为的
let requests = array.map( (item) => {
return new Promise( (resolve) => {
if (item.message.is('link')) {
axios.get(getOpenGraphOfThisLink + item.message)
.then( result => {
item.message =result.data
// console.log(item.message)
// outputs were
//{url:'http://about.com', title:'about'}
//{url:'http://facebook.com', title:'facebook'}
resolve()
})
}
})
})
Promise.all(requests).then( (array) => {
// console.log (array)
// nothing output here
})
promise.all()
将无法运行。 console.log(array)
不会输出任何内容。
答案 0 :(得分:3)
我看到该代码存在三个主要问题:
重要的是,您只有有时解决您在map
回调中创建的承诺;如果item.message.is('link')
为假,您永远不会做任何事情来解决。因此,Promise.all
承诺永远不会解决。
您已接受array
作为Promise.all
then
回调的参数,但它不会成为一个(或者更确切地说,不是有用的)一个)。
您未能通过axios
来电处理失败的可能性。
如果我们通过对数组进行预过滤来解决#2问题,那么当您已经有一个承诺时,您就会创建第四个问题。
相反:
let array = /*...*/;
let requests = array.filter(item => item.message.is('link'))
.map(item => axios.get(getOpenGraphicOfThisLink + item.message)
.then(result => {
item.message = result.data;
return result;
})
);
Promise.all(requests).then(
() => {
// Handle success here, using `array`
},
error => {
// Handle error
}
);
请注意重用axios
承诺会自动将错误传播到链中(因为我们不会向then
或catch
回调提供第二次回调。)
示例(不会显示axios.get
的错误,但......):
// Apparently you add an "is" function to strings, so:
Object.defineProperty(String.prototype, "is", {
value(type) {
return type != "link" ? true : this.startsWith("http://");
}
});
// And something to stand in for axios.get
const axios = {
get(url) {
return new Promise(resolve => {
setTimeout(() => {
resolve({data: "Data for " + url});
}, 10);
});
}
};
// The code:
let array =[ {message:'hello'}, {message:'http://about.com'}, {message:'http://facebook.com'}]
let requests = array.filter(item => item.message.is('link'))
.map(item => axios.get(/*getOpenGraphicOfThisLink + */item.message)
.then(result => {
item.message = result.data;
return result;
})
);
Promise.all(requests).then(
() => {
// Handle success here, using `array`
console.log(array);
},
error => {
// Handle error
console.log(error);
}
);