为什么承诺仍然悬而未决?

Why is the promise still pending?

以下代码returns:

output.isPending?: true
output.isRejected?: false
output.isFulfilled?: false 

为什么?我原以为 output.isRejected 会是 true

<html>

<head>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.7/q.js"></script>
    <script src="http://jasmine.github.io/2.3/lib/jasmine.js"></script>
</head>

<body>
</body>
<script>
var output, bar;

bar = {
    doSomethingAsync: function() {
        var d = Q.defer();
        d.resolve('result');
        return d.promise;
    }
};

function Foo(bar) {
    this._bar = bar;

    this.go = function() {
        var deferred = Q.defer();
        this._bar.doSomethingAsync()
            .then(onSuccess.bind(this, deferred));

        return deferred.promise;
    }
};

function onSuccess(deferred, result) {
    deferred.reject();
}

output = new Foo(bar).go()
    .finally(function() {
        console.log('output.isPending?:', output.isPending());
        console.log('output.isRejected?:', output.isRejected());
        console.log('output.isFulfilled?:', output.isFulfilled());
    });
</script>

</html>

我坚持纠正,即使对于 API 忘记承诺的人来说,一个微不足道的延迟函数也是不必要的。我可以确保 resolvereject 总是被调用,但是在承诺本身被立即返回之后。这是一个例子:

var somePromise = function(path) {
    var deferred = q.defer();

    asyncFunction.request(path, function(result) {
        if (result.error === 0 && result.json !== null) {
            deferred.resolve(result);
        } else {
            deferred.reject(result || {error: -1, message: "bad things happened"});
        }
    });

    return deferred.promise;
};

exports.someCall = function(req,res) {
    somePromise('path')
        .then(function (result) {
            ... do action ...
        }).catch(function (error) {
            ... handle error ...
        }); 
};

因为 output 不是 new Foo(bar).go()。它被分配了 .finally() 调用的结果,并且在 finally 回调完成之前不会被解析。

这将按预期工作:

var output = new Foo(bar).go();
output.finally(function() {
    console.log('output.isPending?:', output.isPending());
    console.log('output.isRejected?:', output.isRejected());
    console.log('output.isFulfilled?:', output.isFulfilled());
});