簡體   English   中英

javascript Promise 等不及 Promise.all

[英]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 黨派並坦率地譴責回調。 這里的含義是我不會用回調編寫你的getDatagetWikiData

我還要指出,我贊同@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM