承诺没有按顺序运行

时间:2014-01-22 05:32:06

标签: javascript angularjs

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

控制器功能:

    $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

1 个答案:

答案 0 :(得分:5)

你正在以错误的方式使用承诺。

第一个问题在这里:

}).then(compare());

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

}).then(compare);

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

您需要以下列方式修改用户服务和控制器才能使其正常工作(使用$q服务来处理承诺):

控制器功能:

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;
}