调用Resolve函数转到JavaScript Promise中的Reject函数(Calling Resolve function goes to Reject function in JavaScript 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(); } });

调用此代码的函数如下:

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

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

编辑:

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

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

关于onreadystatechange的事情是,它被称为MULTIPLE次

关于承诺解决的事情是,一旦被拒绝或解决,它就不能再被拒绝或重新获得

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

如果状态为4并且(DONE)和状态!= 200,则只应拒绝

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

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

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

作为一个有用的东西,但看起来不对的旁注

return new Promise (function (resolve,reject) { if (this.ImageData && averageColor) {

this在承诺构造函数回调内可能是window ,甚至甚至可能在严格模式下undefined - 您需要修复代码,然后导致问题沿着轨道

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 be window, or it even could even be undefined in strict mode - you need to fix that code before it causes issues down the track

更多推荐