简体   繁体   中英

Promise.all failing despite all promises resolving successfully

I am writing a simple Javascript script which uses XMLHttpRequest objects to query an API. There are two main functions within the script; routeLength(startID,endID); and getSystemSecurity(systemID);

The first method returns a Promise object, within with an API call is made:

function routeLength (startID, endID) {
    return new Promise((resolve, reject) => {
        const url = `the request URL`;
        const xml = new XMLHttpRequest();

        xml.onload = function () {
            var systems = this.response.split(',');
            const length = systems.length - 1;
            var routeSecurity = 2;
            var promises = [];
            systems.forEach((element) => {
                if (element[0] == '[') {
                    promises.push(
                        getSystemSecurity(element.substr(1, element.length - 1))
                    );
                }
                else if (element[element.length - 1] == ']') {
                    promises.push(
                        getSystemSecurity(element.substr(0, element.length - 1))
                    );
                }
                else promises.push(getSystemSecurity(element));
            });
            Promise.all(promises).then((values) => {
                values.forEach((v) => {
                    if (v < routeSecurity) routeSecurity = v;
                })
                resolve({"jumps":length,"security":routeSecurity});
            }).catch((error) => {
                reject(error)
            });
        };
    
        xml.open("GET", url);
        xml.send();
    })
}

This method makes a GET request to the API, and performs some logic with the result. The 'systems' array contains system IDs which I have checked are all valid (once the brackets are removed if needed). The promises pushed into the promises array call the following function:

function getSystemSecurity (systemID) {
    return new Promise((resolve,reject) => {
        const url = `${API_URL}/universe/systems/${systemID}`;
        const xml = new XMLHttpRequest();
        xml.onload = function () {
            if (this.response.error) reject(this.response.error);
            const security = this.response["security_status"];
            if (security >= 0.5) resolve(HIGH_SECURITY);
            else if (security < 0.5 && security > 0) resolve(LOW_SECURITY);
            else if (security < 0) resolve(NULL_SECURITY);
            else reject({"error":"Invalid security value " + security});
        }

        xml.onerror = reject("Error executing XMLHttpRequest with ID " + systemID + xml.statusText + xml.responseText);

        xml.open("GET", url);
        xml.send();
    });
}

When I try to run this method, I can see all of the proper requests being made, both the initial request to /route/ as well as the /universe/systems/ routes. Using the developer console I can see that none of them have failed and they all have the expected data. However, I am told that the first promise had failed:

(index):1 Uncaught (in promise) Error executing XMLHttpRequest with ID 30002659

As you can see from the error, xml.statusText and xml.responseText aren't populated, so I cannot determine the actual error that is happening.

So why is Promise.all failing despite all of the requests working with 200 response codes?

The problem is in this line:

xml.onerror = reject("Error executing XMLHttpRequest with ID " + systemID + xml.statusText + xml.responseText);

You are not assigning an event handler, but executing it on the spot!

It should be:

xml.onerror = () => reject("Error executing XMLHttpRequest with ID " + systemID + xml.statusText + xml.responseText);

A general remark: please use the fetch API, it is so much easier to use, and it returns a promise out of the box, so that you can get rid of all those new Promise constructs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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