Javascript 有没有一种方法可以结合蓝鸟';s'then'和'catch'功能?

Javascript 有没有一种方法可以结合蓝鸟';s'then'和'catch'功能?,javascript,promise,bluebird,Javascript,Promise,Bluebird,鉴于此,我有如下代码: // code bits to be executed var X = ...; var pre = ...; var success = ...; var error = ...; var post = ...; X .then(function(val) { pre(val); success(val); post(val); }) .catch(function(err) { pre(); error(err); p

鉴于此,我有如下代码:

// code bits to be executed
var X = ...;
var pre = ...;
var success = ...;
var error = ...;
var post = ...;
X
.then(function(val) {
    pre(val);
    success(val);
    post(val);
})
.catch(function(err) {
    pre();
    error(err);
    post();
});
我会像这样用蓝鸟来运行它:

// code bits to be executed
var X = ...;
var pre = ...;
var success = ...;
var error = ...;
var post = ...;
X
.then(function(val) {
    pre(val);
    success(val);
    post(val);
})
.catch(function(err) {
    pre();
    error(err);
    post();
});
我正在寻找更简单的东西(在这方面,我可以定义更少的
函数
s),大致如下:

X
.complete(function(err, val) {
    pre(val);
    if (err) {
        error(err);
    }
    else {
        success(val);
    }
    post(val);
});
注意,我不能使用
finally
,因为它没有参数,既没有
err
也没有
val
。 还请注意,如果出现错误,
val
假定为
null
未定义

PS:我想得越多,我就越觉得去可能会解决冗长的问题,同时也能保持整洁(保持
if
out并保持事物“可链接”)…

是的,你可以 您可以使用
nodeify
从承诺链中跳出,返回回调区域,它会将节点错误恢复到如下状态:

.nodeify(function(err, val) {
    pre(val);
    if (err) {
        error(err);
    }
    else {
        success(val);
    }
    post(val);
});
这对于需要公开类似节点错误的接口的代码非常有用

但你可能不应该 但是,我不认为在这里使用
.nodeify
是一个很好的主意-相反,您可以:

.finally(pre) // you always need this
.then(success, error) // call success and error and recover
.then(post); // post, this requires that `success` also returns val 
一般来说,你不想有一个成功/失败的函数——这是被调用的,并且指示你应该考虑重构你的代码来接受承诺。 回报承诺 通常,您可以返回承诺,而不是像您的示例中那样进行成功和错误回调-因此,如果您的函数是:

function doStuff(success, error){
    x().then(moreStuff).then(success, error)
}
您使用它的方式如下:
doStuff(成功,错误)

你可以这样写:

function doStuff(){
    return x().then(moreStuff)
}
然后像
doStuff()那样使用它。然后(…)
这允许更容易地链接、聚合和操纵承诺

处理器模式 pre/post的一个常见模式是disposer模式——例如,“pre”表示打开数据库连接,“post”表示关闭数据库连接。这可以表示为:

function withHandle(fn){
    var handle;
    return pre().then(function(resource){ // obtain the resource
       handle = resource; // keep a handle
       return resource;
    }).
    then(fn). // run the actual code for that resource
    finally(function(){
       return handle.close(); // close the resource
    });
}
然后像这样使用:

withHandle(function(handle){
     return handle.query("Give me the first user"); 
}).then(function(result){
    // access result here, the handle is closed, can attach `catch`
});
是的,你可以 您可以使用
nodeify
从承诺链中跳出,返回回调区域,它会将节点错误恢复到如下状态:

.nodeify(function(err, val) {
    pre(val);
    if (err) {
        error(err);
    }
    else {
        success(val);
    }
    post(val);
});
这对于需要公开类似节点错误的接口的代码非常有用

但你可能不应该 但是,我不认为在这里使用
.nodeify
是一个很好的主意-相反,您可以:

.finally(pre) // you always need this
.then(success, error) // call success and error and recover
.then(post); // post, this requires that `success` also returns val 
一般来说,你不想有一个成功/失败的函数——这是被调用的,并且指示你应该考虑重构你的代码来接受承诺。 回报承诺 通常,您可以返回承诺,而不是像您的示例中那样进行成功和错误回调-因此,如果您的函数是:

function doStuff(success, error){
    x().then(moreStuff).then(success, error)
}
您使用它的方式如下:
doStuff(成功,错误)

你可以这样写:

function doStuff(){
    return x().then(moreStuff)
}
然后像
doStuff()那样使用它。然后(…)
这允许更容易地链接、聚合和操纵承诺

处理器模式 pre/post的一个常见模式是disposer模式——例如,“pre”表示打开数据库连接,“post”表示关闭数据库连接。这可以表示为:

function withHandle(fn){
    var handle;
    return pre().then(function(resource){ // obtain the resource
       handle = resource; // keep a handle
       return resource;
    }).
    then(fn). // run the actual code for that resource
    finally(function(){
       return handle.close(); // close the resource
    });
}
然后像这样使用:

withHandle(function(handle){
     return handle.query("Give me the first user"); 
}).then(function(result){
    // access result here, the handle is closed, can attach `catch`
});

然后
回调之前是否调用了
最后
回调?另外,为什么不需要
catch
?@Domi
然后
为错误处理程序获取第二个参数-
.then(…).catch(…)
之间的区别。然后(…,…)
是如果then success处理程序中的代码抛出catch运行,但是在
中(…,)
它们是分开的。
finally
代码是在之前的所有操作完成(无论是否成功)后,在下一个操作完成之前调用的。感谢所有捕获@T.J.Crowder如果您发现任何其他内容,请告诉我。如果在之前的所有操作完成后调用
finally
代码,它不应该用于
而不是
?@Domi X已经是一个承诺-它发生在X
最终完成时。如果您愿意,您也可以将
post
放在finally中,这取决于您希望返回值是什么-在当前代码中,它是post返回的任何内容,如果您将它放在
finally
中,它是任何内容
,那么
成功返回,错误在
然后
回调之前是否调用了
最后
回调?另外,为什么不需要
catch
?@Domi
然后
为错误处理程序获取第二个参数-
.then(…).catch(…)
之间的区别。然后(…,…)
是如果then success处理程序中的代码抛出catch运行,但是在
中(…,)
它们是分开的。
finally
代码是在之前的所有操作完成(无论是否成功)后,在下一个操作完成之前调用的。感谢所有捕获@T.J.Crowder如果您发现任何其他内容,请告诉我。如果在之前的所有操作完成后调用
finally
代码,它不应该用于
而不是
?@Domi X已经是一个承诺-它发生在X
最终完成时。如果您愿意,您也可以将
post
放在finally中,这取决于您希望返回值是什么-在当前代码中,它是post返回的任何内容,如果您将它放在
finally
中,它是任何内容
,那么
成功返回,error@torazaburo:
然后
没有按照OP明确的要求去做。(
nodeify
有。)也许您应该阅读文档。;-)(在那里开玩笑——RTFM通常没有用处,即使是作为一个评论,除非附有他们将在那里看到的相关细节。)@torazaburo:
那么
就不会做OP明确要求的事情。(
nodeify
有。)也许您应该阅读文档。;-)(在那里开玩笑——RTFM通常没有用处,即使是作为一个评论,除非附有他们将在那里看到的相关细节。)