如何将多个 onError 函数分配给一个承诺(由 angular 的 $http.post 返回)
How to assign multiple onError functions to a promise (returned by angular's $http.post)
我的 AngularJS 代码需要将多个 onSuccess
、onError
函数链接到 $http.post
返回的承诺
var promise = $http.post(url);
promise
.then(
/*success 1*/function () { console.log("success 1"); },
/*error 1*/function () { console.log("error 1"); })
.then(
/*success 2*/function () { console.log("success 2"); },
/*error 2*/function () { console.log("error 2"); });
以上代码的问题是当 HTTP 响应失败时它打印 error 1
> success 2
而不是 error 1
> error 2
。
我对 Whosebug 做了一些研究,发现当你可以访问 $q
时,你可以在 error 1
中执行 $q.reject()
来触发 error 2
但在我的例子中我只能访问 $http.post
返回的承诺。那我该怎么办?
P.S. 当然,我可以从 error 1
内部调用 error2()
但我想将它们链接起来,因为它看起来更可读和可扩展。
有什么想法吗?
只需将处理程序包装在一个函数中,在成功/错误处理程序参数中:
var promise = $http.post(url);
promise
.then(function(argX, argY){
success1(argX, argY);
success2(argX, argY);
},
function(argX, argY){
error1(argX, argY);
error2(argX, argY);
});
从 success/error 处理程序返回一个值(或 return 没有值)将解决链中下一个 then 块的承诺。要传播拒绝,return $q.reject():
var promise = $http.post(url);
promise
.then(
/*success 1*/function () { console.log("success 1"); },
/*error 1*/function () { console.log("error 1"); return $q.reject();})
.then(
/*success 2*/function () { console.log("success 2"); },
/*error 2*/function () { console.log("error 2"); });
你的问题源于对 promises 启用的一些误解 - 即异步代码组合与同步代码的组合与 try
/catch
并行,并具有适当的异常处理。
我特指你的说法:
"but i want to chain them because it looks more readable and extensible."
作为链接误解的根源。
如果您的示例是同步的(假设所有异步调用都是阻塞的),这可能是您想要做的:
try {
var data = $http.post(url); // blocking
var res1 = doSuccess1(data);
var ret = doSuccess2(res1);
}
catch(e){
errorHandler1(e);
errorHandler2(e);
}
而不是这个:
try {
try {
var data = $http.post(url);
var res1 = doSuccess1(data);
} catch (e) {
errorHandler1(e);
// throw ""; // this is what returning $q.reject would have done - a rethrow
}
} catch (e) {
errorHandler2(e);
}
var ret = doSuccess2(res1);
这就是您通过链接可以达到的效果。换句话说,嵌套 try
/catch
和 doSuccess2
.
中未处理的异常
以下是第一种方式的异步并行:
var ret;
$http.post(url)
.then(function(data){
var res1 = doSuccess1(data);
ret = doSuccess2(res1);
}
.catch(function(e){ // or .then(null, handler)
doError1(e);
doError2(e);
})
如果 doSuccessN
函数之一也是异步的:
var ret;
$http.post(url)
.then(doSuccess1Async)
.then(function(res1){
ret = doSuccess2(res1);
}
.catch(function(e){ // or .then(null, handler)
doError1(e);
doError2(e);
})
我的 AngularJS 代码需要将多个 onSuccess
、onError
函数链接到 $http.post
var promise = $http.post(url);
promise
.then(
/*success 1*/function () { console.log("success 1"); },
/*error 1*/function () { console.log("error 1"); })
.then(
/*success 2*/function () { console.log("success 2"); },
/*error 2*/function () { console.log("error 2"); });
以上代码的问题是当 HTTP 响应失败时它打印 error 1
> success 2
而不是 error 1
> error 2
。
我对 Whosebug 做了一些研究,发现当你可以访问 $q
时,你可以在 error 1
中执行 $q.reject()
来触发 error 2
但在我的例子中我只能访问 $http.post
返回的承诺。那我该怎么办?
P.S. 当然,我可以从 error 1
内部调用 error2()
但我想将它们链接起来,因为它看起来更可读和可扩展。
有什么想法吗?
只需将处理程序包装在一个函数中,在成功/错误处理程序参数中:
var promise = $http.post(url);
promise
.then(function(argX, argY){
success1(argX, argY);
success2(argX, argY);
},
function(argX, argY){
error1(argX, argY);
error2(argX, argY);
});
从 success/error 处理程序返回一个值(或 return 没有值)将解决链中下一个 then 块的承诺。要传播拒绝,return $q.reject():
var promise = $http.post(url);
promise
.then(
/*success 1*/function () { console.log("success 1"); },
/*error 1*/function () { console.log("error 1"); return $q.reject();})
.then(
/*success 2*/function () { console.log("success 2"); },
/*error 2*/function () { console.log("error 2"); });
你的问题源于对 promises 启用的一些误解 - 即异步代码组合与同步代码的组合与 try
/catch
并行,并具有适当的异常处理。
我特指你的说法:
"but i want to chain them because it looks more readable and extensible."
作为链接误解的根源。
如果您的示例是同步的(假设所有异步调用都是阻塞的),这可能是您想要做的:
try {
var data = $http.post(url); // blocking
var res1 = doSuccess1(data);
var ret = doSuccess2(res1);
}
catch(e){
errorHandler1(e);
errorHandler2(e);
}
而不是这个:
try {
try {
var data = $http.post(url);
var res1 = doSuccess1(data);
} catch (e) {
errorHandler1(e);
// throw ""; // this is what returning $q.reject would have done - a rethrow
}
} catch (e) {
errorHandler2(e);
}
var ret = doSuccess2(res1);
这就是您通过链接可以达到的效果。换句话说,嵌套 try
/catch
和 doSuccess2
.
以下是第一种方式的异步并行:
var ret;
$http.post(url)
.then(function(data){
var res1 = doSuccess1(data);
ret = doSuccess2(res1);
}
.catch(function(e){ // or .then(null, handler)
doError1(e);
doError2(e);
})
如果 doSuccessN
函数之一也是异步的:
var ret;
$http.post(url)
.then(doSuccess1Async)
.then(function(res1){
ret = doSuccess2(res1);
}
.catch(function(e){ // or .then(null, handler)
doError1(e);
doError2(e);
})