大于/小于运算符的行为与 Q 承诺的相等运算符不同

0 javascript comparison promise q

在使用 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);

 });
}
Run Code Online (Sandbox Code Playgroud)

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

如果您使用大于 (>) 或小于 (<) 运算符更改松散相等 (==) 运算符,并更改传递给 resolve() 的值,则代码会按预期工作。

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

谁能解释这种行为?

Fel*_*ing 5

在相等的情况下,结果是false因为您正在比较两个不相同的对象:

规范

7.2.12 抽象相等比较

...
3. 如果Type(x) 和Type(y) 相同,则
    返回执行严格相等比较x === y 的结果。
...

7.2.13 严格相等比较

...
8. 如果 x 和 y 是相同的 Object 值,则返回 true。
9. 返回假。


但是,关系比较仅针对字符串和数字定义。因此 JavaScript在比较 promise 之前执行类型转换。在这个过程中它会调用对象的valueOf方法,所以它实际上将比较的返回值a.valueOfb.valueOf。除此之外,Q 覆盖默认valueOf实现以返回解析值

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

但是你可以看到库不鼓励它,很可能是因为标准承诺没有实现这样的行为。


简化演示:

> var a = {valueOf: function() { return 0; }};
> var b = {valueOf: function() { return 0; }};
> a == b
false
> a >= b
true
Run Code Online (Sandbox Code Playgroud)