在Q中学习承诺和例外与拒绝
我的印象是,承诺内的exception会触发后续的失败处理程序,但在这段代码中看不到它发生:
var Q = require('q'); function x() { console.log('x'); var deferred = Q.defer(); setTimeout( function() { console.log('resolving x'); deferred.resolve('hi'); }, 1000 ); return deferred.promise; } function y() { console.log('y'); var deferred = Q.defer(); setTimeout( function() { console.log('throwing in y'); throw new Error('Oih!'); }, 1000 ); return deferred.promise; } x().then(y).then( function () { console.log('yes'); }, function () { console.log('no'); } );
我做错了什么,还是我误解了?
你正在混合callback和承诺+你有一个延迟反模式的情况。 要么使用Q.delay
或者像下面这样的包装器:
function delay(ms) { var d = Q.defer(); setTimeout(d.resolve, ms); return d.promise; }
现在有超时API的承诺,没有理由使用setTimeout:
function x() { return delay(1000).then(function () { console.log("hi"); }); } function y() { return delay(1000).then(function () { console.log('throwing in y'); throw new Error('Oih!'); }); }
使用:
x() .then(y) .then(function() { console.log('yes'); }) .catch(function(e) { console.log('no'); });
承诺链中的所有exception都被捕获。 您必须像以前一样pipe理失败的承诺,或者使用done()
结束承诺链,以公开并抛出错误(请参阅文档 )。
然而,你抛出setTimeout
的错误与承诺无关,因为错误是asynchronous抛出的,请参阅这个相关的问题 。 另一种方法是拒绝这样的承诺:
function y() { console.log('y'); var deferred = Q.defer(); setTimeout( function() { console.log('throwing in y'); deferred.reject(new Error('Oih!')); }, 1000 ); return deferred.promise; }