最近开始思考是时候对我的逻辑操作进行大规模更新,其中一部分是 Angular JS 异步 Promise 调用的正确链接。给定以下代码,我如何将其重写为两个单独方法的正确链接? (是的,我看过关于此的其他帖子,但它们都涉及其他版本的 Angular 或其他语法,我正在寻找更新的内容。)
vm.functionName = (
function() {
vm.processing = true;
api.promise1({ Id: vm.Id })
.then(
function(result) {
if (result.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
} else {
api.promise2({ param: vm.param })
.then(
function(result2) {
if (result2.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result2.error));
} else {
vm.data = result2.data;
notificationService.success("<h5>Operation successful!.</h5>");
}
vm.processing = false;
}
)
.catch(
function (err) {
console.error(err);
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(err.statusText));
vm.processing = false;
}
);
}
}
)
.catch(
function (err) {
console.error(err);
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(err.statusText));
vm.processing = false;
}
);
}
);
从逻辑上讲,我的大脑告诉我我应该能够做这样的事情:
vm.functionName = (
function() {
vm.processing = true;
vm.promise1()
.then(
vm.promise2()
.then(
notificationService.success("<h5>Operation successful!.</h5>");
vm.processing = false;
);
);
);
}
);
vm.promise1 = (
function() {
api.promise1({ Id: vm.Id })
.then(
function(result) {
if (result.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
}
}
)
.catch(
function (err) {
console.error(err);
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(err.statusText));
}
);
}
);
vm.promise2 = (
function() {
api.promise2({ param: vm.param })
.then(
function(result) {
if (result.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
} else {
vm.data = result2.data;
}
}
)
.catch(
function (err) {
console.error(err);
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(err.statusText));
}
);
}
);
更新: “api....”调用上面对我的 service.js 层的调用,其中方法的存在如下:
promise1: function (params, error) {
return $http
.post("/C#Controller/Method1", params)
.then(handleSuccess)
.catch(function (e) {
handleError(e, error);
});
},
promise2: function (params, error) {
return $http
.post("/C#Controller/Method2", params)
.then(handleSuccess)
.catch(function (e) {
handleError(e, error);
});
},
根据 Pop-A-Stash 的想法进行了更新,现已实现:
//#region Api Calls and Helper
function apiCallOne() {
return api.promise1({ Id: vm.Id });
}
function apiCallTwo() {
return api.promise2({param: vm.param });
}
function handleApiCallError(resultOrError, ngModelToSet) {
var errMsg = resultOrError.statusText === undefined ? resultOrError.error === undefined ? "Unknown Error" : resultOrError.error : resultOrError.statusText;
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(errMsg));
//This allows updating things like variables and ng-model goodies, via an inset function.
if (ngModelToSet) {
ngModelToSet();
}
}
//#endregion
//#region Initialization
function init() {
vm.pgLoaded = false;
apiCallOne()
.then(
function(result) {
if (!result.error) {
vm.data = result.data;
vm.pgLoaded = true;
} else {
handleApiCallError(result, function() { vm.pgLoaded = true; });
}
}
)
.catch(function(errorOne) { handleApiCallError(errorOne, function() { vm.pgLoaded = true; }); });
}
init();
//#endregion
最佳答案
您可以使用递归来调用包含 Promise 及其参数的对象数组中的下一个 Promise,从而显着缩短代码,使用类似于以下内容的方法:
function runPromises(promises) {
var first = promises.shift();
first.function(first.params).then(function(resp) {
if (promises.length > 1) {
runPromises(promises);
}
}).catch(function (error) {
handleError(error);
});
}
初始数组如下:
var promises = [
{
function: promise1,
params: any
},
{
function: promise2,
params: any
}
];
如果每个 Promise 响应需要单独处理,您可以添加一个回调,以便在每个 Promise 的 Promise 得到解决后触发。
关于javascript - 如何: correctly chain AngularJS async calls (AngularJs 1. 7.5),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56690017/