【问题标题】:Promise.all failing despite all promises resolving successfully尽管所有承诺都成功解决,但 Promise.all 失败
【发布时间】:2020-08-23 02:31:40
【问题描述】:

我正在编写一个简单的 Javascript 脚本,它使用 XMLHttpRequest 对象来查询 API。脚本中有两个主要功能; routeLength(startID,endID);getSystemSecurity(systemID);

第一个方法返回一个 Promise 对象,在其中进行 API 调用:

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

此方法向 API 发出 GET 请求,并对结果执行一些逻辑。 'systems' 数组包含我检查过的系统 ID 都是有效的(一旦需要删除括号)。推入 promises 数组的 promise 调用以下函数:

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

当我尝试运行此方法时,我可以看到所有正确的请求,包括对/route/ 的初始请求以及/universe/systems/ 路由。使用开发人员控制台,我可以看到它们都没有失败,并且它们都有预期的数据。然而,我被告知第一个承诺失败了:

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

正如您从错误中看到的那样,xml.statusText 和 xml.responseText 未填充,因此我无法确定正在发生的实际错误。

那么,尽管所有请求都使用 200 个响应代码,但为什么 Promise.all 会失败?

【问题讨论】:

  • 使用更现代的fetch() 而不是XMLHttpRequest,这样做更容易,因为它更健壮并且基于承诺

标签: javascript promise


【解决方案1】:

问题出在这一行:

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

您不是在分配事件处理程序,而是在现场执行它!

应该是:

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

一般性说明:请使用fetch API,它更容易使用,它返回一个开箱即用的承诺,这样你就可以摆脱所有那些new Promise 构造。

【讨论】:

    猜你喜欢
    • 2022-08-20
    • 2017-06-13
    • 2016-01-10
    • 2023-03-23
    • 2021-12-20
    • 2023-01-21
    • 2020-02-29
    • 2018-06-26
    • 1970-01-01
    相关资源
    最近更新 更多