问题
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