Greater/Less than 运算符在 Q promises 上的行为不同于 equal 运算符

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

当使用 Javascript 承诺时,我 运行 陷入了这种奇怪的行为。考虑以下代码:

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

 });
}

当您 运行 此代码时,您会得到 -1。我意识到到那时我还没有评估传递给匿名函数的结果变量(我应该这样做)。我的具体问题是:

如果您将松散相等 (==) 运算符更改为大于 (>) 或小于 (<) 运算符,并更改传递给 resolve() 的值,那么代码将按预期工作.

所以 st运行ge 行为是 == 在 promise 方面的行为不同于 < 或 >。似乎小于 (<) 和大于 (>) 以某种方式具有等待承诺结果的特殊能力,而相等运算符 (==, ===) 则没有。

谁能解释这种行为?

如果相等,结果为 false,因为您比较的是两个不相同的对象:

来自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.
...

7.2.13 Strict Equality Comparison

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


然而,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;
};

但是您可以看到库不鼓励它,很可能是因为 standard promises 没有实现这样的行为。


简化演示:

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