阻止承诺角度

时间:2016-11-16 20:14:46

标签: angularjs

我目前的实施是:

getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
    for (var i in memberIDs) {
        [1]
        getMemberFirstNameWithID(memberIDs[i]).then(function(firstName) {
            [2]
            getMemberLastNameWithID(memberIDs[i]).then(function(lastName) {
                group.members.push({
                    id: memberIDs[i],
                    firstName: firstName,
                    lastName: lastName
                });
            });
        });
        [3]
    }
});

调试时,调用顺序为:

  

[1],[3],[1],[3],[2],[2]

这会在此系统中产生问题,例如,在for循环中,lastName的{​​{1}}实际上将设置为i lastName 1}}。
我已经实施了承诺,并认为它会起作用,但显然不是:

i + 1

我需要调用的顺序为:

  

[1],[2],[3],[1],[2],[3]

那么,在回调一个promise之前,停止执行的最佳方法是什么。基本上,所以承诺是阻止。
如果这不是首选的做法(因为我看到有人说你不应该阻止承诺)< / em>,首选方法是什么?

2 个答案:

答案 0 :(得分:1)

  

基本上,承诺是阻止。

基本上不应该这样做。这不是promises / javascript的工作方式。有办法阻止JS(承诺与否),但实际上,这不符合JavaScript的精神。

您最好的做法是将[3]打包成一个函数(我喜欢使用变量):

var three = function() { [3]; }

然后,在适当的时间(可能是最后.then(...))调用函数three

举个例子:

getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
    for (var i in memberIDs) {
        [1]
        var three = function() { [3]; }
        getMemberFirstNameWithID(memberIDs[i]).then(function(firstName) {
            [2]
            getMemberLastNameWithID(memberIDs[i]).then(function(lastName) {
                group.members.push({
                    id: memberIDs[i],
                    firstName: firstName,
                    lastName: lastName
                });
            });
        }).then(three); //I think this would be the appropriate spot

    }
});

答案 1 :(得分:0)

承诺可以使用。您可以使用$q.all组合多个承诺。每当你有一个承诺返回它,所以调用函数可以等待被调用函数的承诺。并且不要忘记错误处理 - 在每个级别(使用.then时)。通过这种方式,他们不会被吞没到某个地方。当然,除非您在某些时候能够进行有意义的错误处理。

我冒昧地改变了你的代码,所以你可以看到可能的东西。这里最重要的是你可以同时发送名字和姓氏请求(我想它们是对服务器的请求),并且不必等待第一个名字的响应,直到你可以开始请求姓氏。

return getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
  var promises = [],
      memberPromises = [];

  angular.forEach(memberIDs, function(memberId) {
    //[1]
    memberPromises = [];
    memberPromises.push(getMemberFirstNameWithID(memberId));
    memberPromises.push(getMemberLastNameWithID(memberId));

    promises.push($q.all(memberPromises).then(function(responses) {
      //kind of [2], although resolved only when first AND last name are done
      return $q.resolve(group.members.push({
        id: memberId,
        firstName: responses[0],
        lastName: responses[1]
      }));
      //kind of [3], would have to return later then though
    }, function(error) {
      return $q.reject(error);
    })
  });

  return $q.all(promises);
}, function(error) {
  return $q.reject(error);
});

未经测试,但