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 跟踪。现在更困惑了:
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在严格模式下 - 您需要在代码导致问题之前修复该代码