javascript - 如何: correctly chain AngularJS async calls (AngularJs 1. 7.5)

标签 javascript angularjs

最近开始思考是时候对我的逻辑操作进行大规模更新,其中一部分是 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/

相关文章:

javascript - # 出现在 UI.Router 的 URL 中

javascript - ngApp完成处理后如何调用函数?

javascript - 成功返回数据的 Angularjs 路由解析产生未定义的值

javascript - jQuery "chosen": conflict with 'selected' attribute in option tag

javascript - 这可以用 Javascript 或 DHTML 完成吗? (来自闪存)

javascript - Socket.io:如何唯一标识客户端和服务器上的连接?

javascript - AngularJS指令对象有 "No Method"

javascript - AngularJS ng-重复某些过滤表达式

javascript - jQuery data() 和 attr() 方法,以及 JavaScript 数据集属性返回 undefined

javascript - 避免对 Angular.js 中的绑定(bind)值进行不必要的评估