Greater/Less than operator behave differently than equal operator on Q promises

别等时光非礼了梦想. 提交于 2021-01-07 03:30:24

问题


When using Javascript promises, I ran into this weird behavior. Consider the following code:

var Q = require('q');

var d1 = Q.defer();
var d2 = Q.defer();

compare(d1.promise, d2.promise);

d1.resolve(3);
d2.resolve(3);

function compare(a, b) {
 Q.all([a,b]).then(function(results) {
  console.log('a: ' + a + '   b: ' + b);
  var result =  (a == b)? 1: -1;
  console.log(result);

 });
}

When you run this code, you get -1. I realize that I am not evaluating the results variable being passed in to the anonymous function by then (as I should). My specific question is this:

If you change the loose equality (==) operator with a greater than (>) or less than (<) operator, and change the values being passed to resolve(), then the code works as one would expect.

So the strange behavior is that == behaves differently in regards to promises than < or >. It seems as if less than (<) and greater than (>) somehow have a special ability to await the result of promises, while the equality operator (==, ===) does not.

Can anyone explain this behavior?


回答1:


In case of equality the result is false because you are comparing two objects that are not identical:

From the spec:

7.2.12 Abstract Equality Comparison

...
3. If Type(x) is the same as Type(y), then
    Return the result of performing Strict Equality Comparison x === y.
...

and

7.2.13 Strict Equality Comparison

...
8. If x and y are the same Object value, return true.
9. Return false.


However, the relational comparison is only defined for strings and numbers. Hence JavaScript performs type conversion before comparing the promises. In this process it will call the objects' valueOf methods, so it will actually compare the return values of a.valueOf and b.valueOf. In addition to that, Q overrides the default valueOf implementation to return the resolved value:

// XXX deprecated
promise.valueOf = function () {
    if (messages) {
        return promise;
    }
    var nearerValue = nearer(resolvedPromise);
    if (isPromise(nearerValue)) {
        resolvedPromise = nearerValue; // shorten chain
    }
    return nearerValue;
};

But you can see that the library discourages it, most likely because standard promises don't implement such a behavior.


Simplified demonstration:

> var a = {valueOf: function() { return 0; }};
> var b = {valueOf: function() { return 0; }};
> a == b
false
> a >= b
true


来源:https://stackoverflow.com/questions/31664209/greater-less-than-operator-behave-differently-than-equal-operator-on-q-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!