调用 Resolve 函数会转到 JavaScript Promise 中的 Reject 函数

fur*_*866 2 javascript asynchronous promise

我有以下代码:

return new Promise (function (resolve,reject) {
        if (this.ImageData && averageColor) {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
                    console.log("Image found");
                    resolve(xhr.response);
                }else {
                    console.log("Image not found");
                    reject();
                }
            }
            xhr.open('GET', 'http://localhost:8765/color/'+averageColor, true);
            xhr.send(null);
        }
        else {
            reject();
        }
    });
Run Code Online (Sandbox Code Playgroud)

调用这段代码的函数如下:

var v =  tile.getImage(tile.getColorAverage());
        v.then(function (value) {
            console.log("laughing");
        }).catch(function () {
           console.log("Catch called");
        });
Run Code Online (Sandbox Code Playgroud)

问题出在我的承诺中,我可以看到它正在进入 if 条件并正确地从服务器获取响应(因为 console.log)。然而,另一方面,它根本没有进入“然后”的承诺(甚至没有一次)。由于某种原因它会被拒绝。我要疯了,因为我可以看到它执行了应该解决它的位,但我没有得到任何东西。任何帮助将非常感激。

编辑:

现在我只运行了一次。这是我的 console.log 跟踪。现在更困惑了:

在此输入图像描述

Jar*_*a X 5

xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
        console.log(xhr.response);
        resolve(xhr.response);
    }else {
        reject();
    }
}
Run Code Online (Sandbox Code Playgroud)

关于 onreadystatechange 的事情是,它被多次调用

Promise 解决方案的特点是,一旦被拒绝或解决,就不能再次被拒绝或解决

第一次调用 onreadystatechange 时,状态将为 1,而不是 4 ...所以你拒绝

仅当状态为 4 且 (DONE) AND status != 200 时才应拒绝

xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE) {
        if(xhr.status == 200) {
            console.log(xhr.response);
            resolve(xhr.response);
        } else {
            reject();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,使用 onload/onerror - 尽管您仍然需要在 onload 中检查 status == 200

xhr.onload= function () {
    if(xhr.status == 200) {
        console.log(xhr.response);
        resolve(xhr.response);
    } else {
        reject();
    }
}


xhr.onerror= function () {
    reject();
}
Run Code Online (Sandbox Code Playgroud)

作为一些有用但看起来错误的东西的旁注

return new Promise (function (resolve,reject) {
    if (this.ImageData && averageColor) {
Run Code Online (Sandbox Code Playgroud)

this在 Promise 构造函数回调中可能是这样window,甚至可能是undefined在严格模式下 - 您需要在代码导致问题之前修复该代码