我有一个这样的数组
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)
不输出任何内容。
最佳答案
我发现该代码存在三个主要问题:
关键的是,您只是有时解决了您在
map
中创建的 promise 。打回来;如果item.message.is('link')
是假的,你永远不会做任何事情来解决。因此,Promise.all
promise 永远不会解决。您正在接受
array
作为你的Promise.all
的论据then
回调,但它不会是一个(或者更确切地说,不是一个有用的)。您没有处理来自
axios
的失败可能性打电话。
如果我们通过预过滤数组解决 #2,那么还有第四个问题,即当您已经有一个可以使用的 promise 时,您正在创建一个 promise 。
相反:
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
promise 自动将错误传播到链中(因为我们没有提供到 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);
}
);
关于javascript - 将数组中的数据映射到 Promises 并在 Promise.all() 上执行代码不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40681723/