[英]javascript Promise not wait Promise.all
因此getAstronautsData向 API 發出請求,然后返回承諾數組。 這承諾向 Wiki API 發出請求,並在 object 中解析響應。 然后exampleAsyncFunc必須等待所有的 Promise 並返回一個大的 object,其中包含有關宇航員的所有信息。 但是如果我使用Promise.all function 結尾和控制台就很清楚了。
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)
}
}
})
}
You appear to be using Promise.all
correctly, but if any of the Promises in Promise.all
rejects, then overall Promise.all
promise will reject too and nothing will happen, where in your forEach
version it'll simply skip those promises silently and繼續下一個條目。
同樣,如果列表中的任何承諾保持未決:如果是這樣,那么Promise.all
promise 將永遠無法解決。 這可能是因為您的返回值列表很長,並且整個列表需要比預期更長的時間來解決,或者因為您的getWikiData
調用遇到錯誤並且您沒有將其傳遞出去以拒絕您的特定 promise大批。
您可以通過確保對then
的每個調用都后跟.catch(console.error)
(或更強大的錯誤處理程序)來調試此行為。
首先讓我透露一下,我是一個大的 promise 黨派並坦率地譴責回調。 這里的含義是我不會用回調編寫你的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
並從 function 內部調用它,其中包含您最終要解決的承諾數組。 如您所見,這里也不需要async
。
好的,問題出在 API 中(在 API 中,其中一名宇航員的名字是"Tom Marshburn"
,但在 Wiki 上他的頁面標題為"Thomas Marshburn"
),並且getWikiData
上的任何數據都不會返回錯誤。 所以我解決了這個問題。 謝謝大家的幫助!!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.