javascript - promise 未按顺序运行

标签 javascript angularjs

我的 Controller 中有一个功能可以将用户添加到组中,一旦将用户分配到组中,可用组列表就会减少。我尝试在我的函数中使用 promises 来控制流程,但根据控制台日志,我的所有 groupServices 都先运行,然后 userServices 在之后运行,从而阻止可用组列表更新更正。

Controller 函数:

    $scope.addUserToGroup = function (){
        var defer = $q.defer();
        defer.promise.then(function (){
            userService.addUserToGroup(
                $scope.selectedUser, 
                $scope.selectedAvailableGroups, 
                $scope.assignedGroups, 
                $scope.availableGroups,
                $scope.groups
            ); 
        }).then(compare());
        defer.resolve();
    };
    function compare(){
    console.log('comparing assigned with all ');
        $scope.compareGroups = groupService.compareGroups();         
    }

我正在使用 promises 试图确保事情按顺序运行,但根据我的控制台输出,情况似乎并非如此。

用户服务功能

  var addUserToGroup = function (selectedUser, selectedAvailableGroups, assignedGroups, availableGroups, groups){

    console.dir(selectedUser);
    console.dir(selectedAvailableGroups);
    console.dir(assignedGroups);
    console.dir(availableGroups);
    console.dir(groups);

    var deferred = $q.defer();

    var addPromise = [];
    var selectLength = selectedAvailableGroups.length;

    //Add user to selected groups on server
    deferred.promise
      .then(function (){ 
        for (var i = 0; i < selectLength; i++){
          addPromise[i] = $().SPServices({
            operation: "AddUserToGroup",
            groupName: selectedAvailableGroups[i].name,
            userLoginName: selectedUser.domain
          });      
        }; 
      })
      .then(function (){
          //when promise finished, push changes to availableGroups
          for (var i = 0; i < selectLength; i++){
            assignedGroups.push(selectedAvailableGroups[i]);
            console.log(selectedUser.name + " added to: " + selectedAvailableGroups[i].name);
          };
      });
    //Run
    deferred.resolve();
  }

群服务功能:

var compareGroups = function () {
    //Comparing assigned groups with allGroups to return available groups
    var assignedGroupsIds = {};
    var groupsIds = {};
    var result = []
    availableGroups = [];
    console.log('assigned');
    console.dir(assignedGroups);
    console.log('avail');

    assignedGroups.forEach(function (el, i) {
        assignedGroupsIds[el.id] = assignedGroups[i];
    }); 

    allGroups.forEach(function (el, i) {
        groupsIds[el.id] = allGroups[i];
    });   

    for (var i in groupsIds) {
        if (!assignedGroupsIds.hasOwnProperty(i)) {
            result.push(groupsIds[i]);
            availableGroups.push(groupsIds[i]);

        }
    };
    console.dir(result);
    console.dir(availableGroups);
}

控制台日志:

comparing assigned with all  userCtrl.js:47
assigned groups             groupServices.js:63
Array[8]                    groupServices.js:64
available gruops            groupServices.js:65
Array[3]                    groupServices.js:82
Array[3]                    groupServices.js:83
Object                      userServices.js:38
Array[1]                    userServices.js:39
Array[8]                    userServices.js:40
Array[4]                    userServices.js:41
Array[11]                   userServices.js:42
User added to: Test Group 4 userServices.js:64

最佳答案

您以错误的方式使用了 promises。

第一个问题在这里:

}).then(compare());

您正在尝试将 compare 函数的执行结果注册为回调,而不是像这样仅注册 compare 函数:

}).then(比较);

这就是为什么它首先执行,然后调用 groupService.compareGroups() 并且只有在它完成后,您才调用 defer.resolve() 并且您的第一个注册回调执行.这就是您看到当前控制台输出的原因。

您需要按照以下方式修改用户服务和 Controller 以使其正常工作(使用 $q 服务来处理 promise ):

Controller 函数:

function compare(){
    console.log('comparing assigned with all ');
    $scope.compareGroups = groupService.compareGroups();         
}

$scope.addUserToGroup = function (){
    userService.addUserToGroup(
        $scope.selectedUser, 
        $scope.selectedAvailableGroups, 
        $scope.assignedGroups, 
        $scope.availableGroups,
        $scope.groups
    ).then(compare); 
};

用户服务功能:

(假设 $().SPServices 返回 Promise)

var addUserToGroup = function (selectedUser, selectedAvailableGroups, assignedGroups, availableGroups, groups){

    console.dir(selectedUser);
    console.dir(selectedAvailableGroups);
    console.dir(assignedGroups);
    console.dir(availableGroups);
    console.dir(groups);

    var deferred = $q.defer();

    var addPromise = [];
    var selectLength = selectedAvailableGroups.length;

    //Add user to selected groups on server
    for (var i = 0; i < selectLength; i++){
        addPromise[i] = $().SPServices({
            operation: "AddUserToGroup",
            groupName: selectedAvailableGroups[i].name,
            userLoginName: selectedUser.domain
        });      
    }

    $q.all(addPromise).then(function (){
        //when promise finished, push changes to availableGroups
        for (var i = 0; i < selectLength; i++){
            assignedGroups.push(selectedAvailableGroups[i]);
            console.log(selectedUser.name + " added to: " + selectedAvailableGroups[i].name);
        };

        //Finish function
        deferred.resolve();
    });
    return deferred.promise;
}

关于javascript - promise 未按顺序运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21274972/

相关文章:

javascript - 将 <ol> append 到 <div> 元素的 <li> 会导致恼人的错误

javascript - POPUP 窗口中的 Ext Dependency Builder

javascript - 从后面将字符串拆分为数组

javascript - for 循环中的 if 语句同时执行,而不是只执行一个

javascript - 有没有办法获取从 npm 运行的模块中的 package.json 属性?

javascript - 如何将事件传递到动力学中的以下节点

css - 如何在Daypilot Scheduler上删除DEMO

javascript - 如何使用 Angular 和 php 读取 bool 值

css - Angular Material 按钮禁用样式更改

javascript - Angular js- Controller 仅在页面刷新时加载