【问题标题】:javascript Promise not wait Promise.alljavascript Promise 不等待 Promise.all
【发布时间】:2022-01-11 02:42:06
【问题描述】:

所以 getAstronautsData 向 API 发出请求,然后返回一系列承诺。这承诺向 Wiki API 发出请求并解析对象中的响应。然后 exampleAsyncFunc 必须等待所有的 Promise 并返回一个包含所有宇航员信息的大对象。 但是如果我使用 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)
            }


        }

    })
}

【问题讨论】:

  • 你没有拒绝任何东西。我想这就是为什么你什么都看不到的原因,因为他们默默地拒绝
  • 函数exampleAsyncFunc 是否与您在测试用例中的完全一样。因为以该顺序同时在同一函数中同时使用 let data = await Promise.all(promisesList)promisesList.forEach((promise) => { 并让 forEach 正常工作是没有意义的。
  • 问题出在getWikiData 函数中。对于这些请求之一,数据请求可能会失败,并且由于您没有处理错误情况,因此承诺保持挂起(看起来您无法处理错误情况,因为回调似乎没有错误参数)。 getData 似乎也容易出现这个问题。
  • @t.niese 好的,我可以在所有可以添加的地方添加 catch。没用

标签: javascript async-await promise es6-promise


【解决方案1】:

您似乎正确地使用了Promise.all,但如果Promise.all 中的任何 Promise 被拒绝,那么整个Promise.all 承诺也将被拒绝并且不会发生任何事情,在您的@ 987654324@ 版本,它会默默地跳过这些承诺并继续下一个条目。

同样,如果列表中的任何承诺保持未决:如果是这样,那么Promise.all 承诺将永远不会解决。这可能是因为您的返回值列表很长,并且整个列表需要比预期更长的时间来解决,或者因为您的 getWikiData 调用遇到错误并且您没有传递该错误以拒绝该特定承诺在你的数组中。

您可以通过确保每次调用then 后跟.catch(console.error)(或一些更强大的错误处理程序)来调试此行为。

【讨论】:

    【解决方案2】:

    首先让我透露一下,我是一个大承诺党派,并坦率地谴责回调。这里的意思是我不会用回调写你的getDatagetWikiData

    我还要指出,我赞同 @t.niese 在 cmets 中所说的话: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

    【讨论】:

    • 谢谢,但它仍然无法正常工作))脚本等待几秒钟然后结束
    【解决方案3】:

    好的,问题出在 API 中(在 API 中,一名宇航员的名字为 "Tom Marshburn",但在 Wiki 上,他的页面的标题为 "Thomas Marshburn")和函数 getWikiData 不返回任何错误数据。所以我解决了这个问题。 谢谢大家的帮助!!!

    【讨论】:

    • 这并不能真正解决根本问题。你真的应该修复你 getData 函数和 getAstronautsData 来处理错误并将它们传递给回调。
    • 谢谢,我知道错误处理,这段代码是我项目的原型,所有错误处理,还有其他问题,我稍后会解决。
    猜你喜欢
    • 2020-06-23
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2018-12-02
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    相关资源
    最近更新 更多