2015-05-19 37 views
5

下面的代码返回:为什么这个承诺还在等待呢?

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

为什么?我期待output.isRejectedtrue

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

回答

5

因为outputnew 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()); 
}); 
+0

从https://github.com/kriskowal/q - '如果处理程序返回一个promise,outputPromise会被推迟.....' – Adam

0

我认错一个微不足道的延迟功能是不必要的甚至是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 ... 
     }); 
}; 
+1

没有必要为'resolve'或'返回一个承诺后才reject'。不论何时/如何解决您的承诺,所有回调都是异步调用的。使用这样的延迟甚至看起来有点像[常见反模式](http://stackoverflow.com/q/23803743/1048572)。 – Bergi

+0

此代码仍然允许承诺被链接,例如: 'exports.someCall =函数(REQ,RES){ somePromise( '路径') 。然后(函数(结果){ 返回somePromise( '新路径' ); })。然后(函数(结果){ ...做别的事情......' –

+0

是的,但是'q.delay(1)'仍然是不必要的? – Bergi