I have the following code:
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();
}
});
The function that calls this code is as follows:
var v = tile.getImage(tile.getColorAverage());
v.then(function (value) {
console.log("laughing");
}).catch(function () {
console.log("Catch called");
});
The issue is in my promise I can see that it is going in that if condition and getting the response from the server correctly (because of the console.log). However, on the other side, it doesn't go into 'then' bit of promise at all (not even once). It goes to the reject one for some reason. I am going nuts as I can see it executes the bit which is supposed to resolve it but I don't get anything in then. Any help would be much appreciated.
Edited:
Now I just ran it once. And here is my console.log trace. Now even more confused:
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
console.log(xhr.response);
resolve(xhr.response);
}else {
reject();
}
}
The thing about onreadystatechange is, it gets called MULTIPLE times
The thing about promise resolution is that once rejected or resolved, it can not be rejected or resovled again
The first time onreadystatechange gets called, the status would be 1, not 4 ... so you reject
you should only reject if status is 4 and (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();
}
}
}
Alternatively, use onload/onerror - though you still need to check for status == 200 in onload
xhr.onload= function () {
if(xhr.status == 200) {
console.log(xhr.response);
resolve(xhr.response);
} else {
reject();
}
}
xhr.onerror= function () {
reject();
}
as a side note about something that works but looks wrong
return new Promise (function (resolve,reject) {
if (this.ImageData && averageColor) {
this
inside the promise constructor callback could bewindow
, or it even could even beundefined
in strict mode - you need to fix that code before it causes issues down the track
The reason you are having this issue is that onreadystatechange
is called multiple times before the request completes and before it is DONE you will get your else
condition which calls reject
. You should only reject if DONE
AND xhr.status != 200
. Here is an example:
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject();
}
}
this
within Promise
constructor is window
, unless specifically set to a different value. this.ImageData
would evaluate to false
without setting this
to the object that has .ImageData
as a property at call to new Promise()
.
Substitute reference to object that has property ImageData
for this.ImageData
within Promise
constructor resolver function.
For example
function resolver(resolve, reject) {
}
new Promise(resolver.bind(/*object that has `.ImageData` as property*/))
Also, substitute load
event for readystatechange
event and include error
event handler for XMLHttpRequest
object.
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.