简体   繁体   English

javascript Promise 等不及 Promise.all

[英]javascript Promise not wait Promise.all

So getAstronautsData make request to API then return array of promises.因此getAstronautsData向 API 发出请求,然后返回承诺数组。 This promises mast make request to Wiki API and parse response in object.这承诺向 Wiki API 发出请求,并在 object 中解析响应。 Then exampleAsyncFunc must wait all promises and return one big object with all info about Astronauts.然后exampleAsyncFunc必须等待所有的 Promise 并返回一个大的 object,其中包含有关宇航员的所有信息。 But if I use Promise.all function ending and console is clear.但是如果我使用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 move on to the next entries. 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继续下一个条目。

Likewise if any of the promises in the list stays pending: if so then the Promise.all promise will never resolve.同样,如果列表中的任何承诺保持未决:如果是这样,那么Promise.all promise 将永远无法解决。 This could be because you have a long list of return values and the whole list takes a longer-than-expected time to resolve, or because your getWikiData call encounters an error and you don't pass that out to reject that particular promise in your array.这可能是因为您的返回值列表很长,并且整个列表需要比预期更长的时间来解决,或者因为您的getWikiData调用遇到错误并且您没有将其传递出去以拒绝您的特定 promise大批。

You can debug this behavior by ensuring that each of your calls to then is followed by .catch(console.error) (or some more robust error handler).您可以通过确保对then的每个调用都后跟.catch(console.error) (或更强大的错误处理程序)来调试此行为。

Let me first disclose that I am a big promise partisan and frankly deplore callbacks.首先让我透露一下,我是一个大的 promise 党派并坦率地谴责回调。 The implication here is that I would not have written your getData and getWikiData with callbacks.这里的含义是我不会用回调编写你的getDatagetWikiData

I will also point out that I second what @t.niese said in the comments: Because it does not make sense having both let data = await Promise.all(promisesList) and promisesList.forEach((promise) => { .我还要指出,我赞同@t.niese 在评论中所说的话: Because it does not make sense having both let data = await Promise.all(promisesList) and promisesList.forEach((promise) => {

Anyway, your code is unnecessarily complex and can be simplified like so:无论如何,您的代码过于复杂,可以像这样简化:

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 ()

Notice that I am passing a callback to getAstronautsData and call it from inside that function with the array of promises you ultimately want to resolve.请注意,我将一个回调传递给getAstronautsData并从 function 内部调用它,其中包含您最终要解决的承诺数组。 No need for async here either as you can see.如您所见,这里也不需要async

Ok, problem was in API (in API one of astronauts have name "Tom Marshburn" but on Wiki his page have title "Thomas Marshburn" ) and function getWikiData not return any data on error.好的,问题出在 API 中(在 API 中,其中一名宇航员的名字是"Tom Marshburn" ,但在 Wiki 上他的页面标题为"Thomas Marshburn" ),并且getWikiData上的任何数据都不会返回错误。 So i fixed this problem.所以我解决了这个问题。 Thanks you all for you help!!!谢谢大家的帮助!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM