javascript答应不等Promise.all
javascript Promise not wait Promise.all
因此 getAstronautsData 向 API 提出请求,然后 return 承诺数组。这承诺会向 Wiki API 发出请求并解析对象中的响应。然后 exampleAsyncFunc 必须等待所有的承诺和 return 一个包含所有关于宇航员信息的大对象。
但是如果我使用 Promise.all 函数结束并且控制台是清晰的。
function getAstronautsData() {
return new Promise((resolve, reject) => {
getData('http://api.open-notify.org/astros.json', "http", (data) => {
resolve(data) // get Astronauts list from API
})
}).then((astronautsList) => {
return astronautsList.people.map((person => // return array of promises
new Promise(resolve => {
getWikiData(person.name, (data) => { // request on Wiki API
resolve({info: data.extract, img: data.thumbnail.source})
})
})
))
})
}
async function exampleAsyncFunc (){
let promisesList = await getAstronautsData()
// next code just few variant was i try
let data = await Promise.all(promisesList)// it's not working.
console.log(data)
Promise.all(promisesList).then(data => console.log(data)) //it's not working. Function display nothing
promisesList.forEach((promise) => { //it's working but not so elegant
promise.then(data => console.log(data))
})
}
exampleAsyncFunc ()
function getWikiData(searhTerm, callback) {
getData(getUrlString(searhTerm), "https", (data) => {
const regex = new RegExp(searhTerm.replaceAll(" ", ".*"));
for (let page in data.query.pages) {
if (data.query.pages[page].title === searhTerm || regex.test(data.query.pages[page].title)) {
callback(data.query.pages[page])
return
}else{
callback(null)
}
}
})
}
您似乎正确地使用了 Promise.all
,但是如果 中的任何 的 Promise.all
承诺被拒绝,那么总体 Promise.all
承诺将reject 也不会发生任何事情,在你的 forEach
版本中,它只会默默地跳过这些承诺并继续下一个条目。
同样,如果列表中的任何承诺仍处于未决状态:如果是这样,那么 Promise.all
承诺将永远不会解决。这可能是因为您有一长串 return 值并且整个列表需要比预期更长的时间来解决,或者因为您的 getWikiData
调用遇到错误而您没有通过在你的数组中拒绝那个特定的承诺。
您可以通过确保每次调用 then
后跟 .catch(console.error)
(或更强大的错误处理程序)来调试此行为。
首先让我透露一下,我是一个很有希望的党派,坦率地说,我对回调表示遗憾。这里的含义是我不会用回调写你的getData
和getWikiData
。
我还要指出,我支持@t.niese 在评论中所说的:Because it does not make sense having both let data = await Promise.all(promisesList) and promisesList.forEach((promise) => {
.
无论如何,您的代码不必要地复杂,可以像这样简化:
function getAstronautsData(callback) {
getData('http://api.open-notify.org/astros.json', "http", data => {
callback(data.people.map(person =>
new Promise(resolve => {
getWikiData(person.name, data => {
resolve(data);
})
}))
)
})
}
function exampleAsyncFunc (){
getAstronautsData(promises => {
Promise.all(promises)
.then(result => {
//result will contain those resolved promises
console.log(result);
})
});
}
exampleAsyncFunc ()
请注意,我将回调传递给 getAstronautsData
并从该函数内部使用您最终想要解决的承诺数组调用它。如您所见,这里也不需要 async
。
好的,问题出在 API(在 API 中,一位宇航员的名字是 "Tom Marshburn"
,但在 Wiki 上,他的页面的标题是 "Thomas Marshburn"
)和功能 getWikiData
不是 return 任何关于错误的数据。所以我解决了这个问题。
谢谢大家的帮助!!!
因此 getAstronautsData 向 API 提出请求,然后 return 承诺数组。这承诺会向 Wiki API 发出请求并解析对象中的响应。然后 exampleAsyncFunc 必须等待所有的承诺和 return 一个包含所有关于宇航员信息的大对象。 但是如果我使用 Promise.all 函数结束并且控制台是清晰的。
function getAstronautsData() {
return new Promise((resolve, reject) => {
getData('http://api.open-notify.org/astros.json', "http", (data) => {
resolve(data) // get Astronauts list from API
})
}).then((astronautsList) => {
return astronautsList.people.map((person => // return array of promises
new Promise(resolve => {
getWikiData(person.name, (data) => { // request on Wiki API
resolve({info: data.extract, img: data.thumbnail.source})
})
})
))
})
}
async function exampleAsyncFunc (){
let promisesList = await getAstronautsData()
// next code just few variant was i try
let data = await Promise.all(promisesList)// it's not working.
console.log(data)
Promise.all(promisesList).then(data => console.log(data)) //it's not working. Function display nothing
promisesList.forEach((promise) => { //it's working but not so elegant
promise.then(data => console.log(data))
})
}
exampleAsyncFunc ()
function getWikiData(searhTerm, callback) {
getData(getUrlString(searhTerm), "https", (data) => {
const regex = new RegExp(searhTerm.replaceAll(" ", ".*"));
for (let page in data.query.pages) {
if (data.query.pages[page].title === searhTerm || regex.test(data.query.pages[page].title)) {
callback(data.query.pages[page])
return
}else{
callback(null)
}
}
})
}
您似乎正确地使用了 Promise.all
,但是如果 中的任何 的 Promise.all
承诺被拒绝,那么总体 Promise.all
承诺将reject 也不会发生任何事情,在你的 forEach
版本中,它只会默默地跳过这些承诺并继续下一个条目。
同样,如果列表中的任何承诺仍处于未决状态:如果是这样,那么 Promise.all
承诺将永远不会解决。这可能是因为您有一长串 return 值并且整个列表需要比预期更长的时间来解决,或者因为您的 getWikiData
调用遇到错误而您没有通过在你的数组中拒绝那个特定的承诺。
您可以通过确保每次调用 then
后跟 .catch(console.error)
(或更强大的错误处理程序)来调试此行为。
首先让我透露一下,我是一个很有希望的党派,坦率地说,我对回调表示遗憾。这里的含义是我不会用回调写你的getData
和getWikiData
。
我还要指出,我支持@t.niese 在评论中所说的:Because it does not make sense having both let data = await Promise.all(promisesList) and promisesList.forEach((promise) => {
.
无论如何,您的代码不必要地复杂,可以像这样简化:
function getAstronautsData(callback) {
getData('http://api.open-notify.org/astros.json', "http", data => {
callback(data.people.map(person =>
new Promise(resolve => {
getWikiData(person.name, data => {
resolve(data);
})
}))
)
})
}
function exampleAsyncFunc (){
getAstronautsData(promises => {
Promise.all(promises)
.then(result => {
//result will contain those resolved promises
console.log(result);
})
});
}
exampleAsyncFunc ()
请注意,我将回调传递给 getAstronautsData
并从该函数内部使用您最终想要解决的承诺数组调用它。如您所见,这里也不需要 async
。
好的,问题出在 API(在 API 中,一位宇航员的名字是 "Tom Marshburn"
,但在 Wiki 上,他的页面的标题是 "Thomas Marshburn"
)和功能 getWikiData
不是 return 任何关于错误的数据。所以我解决了这个问题。
谢谢大家的帮助!!!