我有以下代码:
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();
}
});
调用此代码的函数如下:
var v = tile.getImage(tile.getColorAverage());
v.then(function (value) {
console.log("laughing");
}).catch(function () {
console.log("Catch called");
});
问题在于我的承诺我可以看到,如果条件正确并且从服务器正确获取响应(因为console.log)。但是,另一方面,它并没有进入'然后'有点承诺(甚至没有一次)。出于某种原因,它会被拒绝。我疯了,因为我可以看到它执行了应该解决它的位但我当时没有得到任何东西。任何帮助将不胜感激。
编辑:
现在我只跑了一次。这是我的console.log跟踪。现在更加困惑:
答案 0 :(得分:4)
Program
关于onreadystatechange的事情是,它被称为MULTIPLE次
关于承诺解决的事情是,一旦被拒绝或解决,就不能再被拒绝或重新获得
第一次调用onreadystatechange时,状态为1,而不是4 ......所以你拒绝
如果状态为4且(DONE)AND状态!= 200
,则只应拒绝xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
console.log(xhr.response);
resolve(xhr.response);
}else {
reject();
}
}
或者,使用onload / onerror - 尽管你仍然需要在onload中检查状态== 200
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
if(xhr.status == 200) {
console.log(xhr.response);
resolve(xhr.response);
} else {
reject();
}
}
}
作为关于可行但看起来不对的事情的旁注
xhr.onload= function () {
if(xhr.status == 200) {
console.log(xhr.response);
resolve(xhr.response);
} else {
reject();
}
}
xhr.onerror= function () {
reject();
}
promise构造函数回调中的
return new Promise (function (resolve,reject) { if (this.ImageData && averageColor) {
可以是this
,或者甚至可以在严格模式下window
- 您需要修复该代码才能导致问题进入轨道< / p>
答案 1 :(得分:1)
您遇到此问题的原因是onreadystatechange
在请求完成之前被多次调用,在完成之前,您将获得调用else
的{{1}}条件。您应该只拒绝reject
和DONE
。这是一个例子:
xhr.status != 200
答案 2 :(得分:0)
this
构造函数中的{p> Promise
为window
,除非明确设置为其他值。 this.ImageData
评估为false
而不会将this
设置为.ImageData
作为调用new Promise()
的属性的对象。
在ImageData
构造函数解析器函数中替换对this.ImageData
具有属性Promise
的对象的引用。
例如
function resolver(resolve, reject) {
}
new Promise(resolver.bind(/*object that has `.ImageData` as property*/))
另外,将load
事件替换为readystatechange
事件,并为error
对象添加XMLHttpRequest
事件处理程序。