Re: https://github.com/tildeio/rsvp.js
我有一个名为doSomething()的函数,它可以做一段时间的事情,然后返回回复。承诺。然后,成功和失败回调链是使用返回的承诺注册(请参阅下面的代码)。我期望的行为如果承诺实现,则成功回调链注册为承诺将被触发,如果承诺被拒绝(失败),则链将触发失败回调。
我得到了承诺实现时的预期行为,但我得到了当承诺被拒绝时,行为与我的预期不同。那是成功回调被链接,一个成功回调的输出被传递给链中的下一个成功回调。但似乎失败回调未链接。它们的行为几乎类似于 try/catch 块中的捕获(请参阅代码和输出如下)。
有人可以解释这种行为吗?这真的是它应该的工作方式,还是这个RSVP.js 处理已拒绝/失败的承诺的方式中存在错误,该承诺注册了一连串失败回调?我现在正在阅读 Promises/A+ 规范以尝试解决这个问题,但如果有人知道这些东西,很想听听你的解释。提前谢谢。
JSFIDDLE: http://jsfiddle.net/rylie/VYSj7/2/
doSomething() // returns an RSVP.Promise object
.then(
function(message) { console.log("then success 1: " + message); return "from success 1"; }, // success callback
function(message) { console.log("then failure 1: " + message); return "from failure 1"; } // failure callback
)
.then(
function(message) { console.log("then success 2: " + message); return "from success 2"; }, // success callback
function(message) { console.log("then failure 2: " + message); return "from failure 2"; } // failure callback
)
.then(
function(message) { console.log("then success 3: " + message); return "from success 3"; } // success callback
)
.then(
null,
function(message) { console.log("then failure 4: " + message); return "from failure 4"; } // failure callback
)
.then(
function(message) { console.log("then success 5: " + message); return "from success 5"; }, // success callback
function(message) { console.log("then failure 5: " + message); return "from failure 5"; } // failure callback
);
** 当承诺实现(成功)时,这是我得到和预期的输出:
then success 1: Promise fulfilled!
then success 2: from success 1
then success 3: from success 2
then success 5: from success 3
** 当承诺被拒绝(失败)时,这是我得到的输出:
then failure 1: Promise rejected!
then success 2: from failure 1
then success 3: from success 2
then success 5: from success 3
**这是我所期望的(被拒绝/失败的承诺):
then failure 1: Promise rejected!
then failure 2: from failure 1
then failure 4: from failure 2
then failure 5: from failure 4
忘记.then()
甚至需要 1 个以上的参数并使用 .catch
方法,它会更有意义。
承诺提供了与某些同步代码构造的对应关系,但是当您只有一个低级.then()
时,这不是很明显。您正在寻找的基本上是一个回调/回调聚合数组,但这根本不是承诺的重点。
.catch(fn)
想一想.then(null, fn)
:
doSomething().then(function(val) {
console.log(val);
}).catch(function(e) {
console.error(e);
});
与同步代码并行(想象一下doSomething
同步返回):
try {
var val = doSomething();
console.log(val);
}
catch(e) {
console.error(e);
}
多个捕获(请记住,.catch
更易于读取的别名.then(null, fn)
doSomething().then(function(val) {
console.log(val);
}).catch(function(e) {
return e;
}).catch(function(e){
//Will not get here ever
//because error thrown from doSomething()
//was handled in the upper catch which doesn't trow
});
相似 之 处:
try {
try {
var val = doSomething();
console.log(val);
}
catch(e) {
//no need for explicit return e
}
}
catch( e ) {
//Will not get here ever
//because error thrown from doSomething()
//was handled in the upper catch which doesn't trow
}
所以现在你应该注意到,你可以通过抛出而不是返回 http://jsfiddle.net/VYSj7/3/来创建预期的结果
.catch()
IMO是承诺库提供的基本方法,将来也将包含在内置的Javascript承诺中。然而如果没有提供这样的方法,你可以(或者应该提供,不幸的是,有些实现不使用原型):
Promise.prototype.catch = function(fn) {
return this.then(null, fn);
};
参见 拒绝变成满足