管理 angularjs 嵌套承诺以建立从服务器返回的响应

Managing angularjs nested promises to build response back from the server

我正在使用 angular 从服务器建立响应以显示私人消息。到目前为止,我有这段代码可以正常工作,但它看起来不像是使用 promises 的正确方式,特别是用于处理错误。我想知道我应该如何使用最佳实践来处理这种情况下的嵌套承诺?

function listenMessageSend(data) {

var imData = {
  message: data.data.id,
  sender: currentUser().id,
  reciever: $scope.reciever
}

Im.create(imData).then(function(im) {
  Message.update(im.data.message, {im: im.data.id}).then(function(msg) {
    User.get(msg.data.im.sender).then(function(sender) {
      msg.data.im.sender = sender.data;
      User.get(msg.data.im.reciever).then(function(reciever) {
        msg.data.im.reciever = reciever.data;
      });   
    });
    if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
      $scope.messages.push(msg.data);
    }
  })
});

};

if必须留在更深层的承诺中,因为它最终会得到解决:

User.get(msg.data.im.sender).then(function(sender) {
  msg.data.im.sender = sender.data;
  User.get(msg.data.im.reciever).then(function(reciever) {
    msg.data.im.reciever = reciever.data;
    if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
      $scope.messages.push(msg.data);
    }
  });   
});

您可以在获取接收方数据的同时获取发送方数据。你不应该嵌套两个上下文独立的承诺,因为它会导致糟糕的用户体验,因为你正在等待 "sender" 响应结束以发出获取 "receiver" 数据的请求,而浏览器可以完美的同时处理这两个请求

请同时发出这两个请求,等待两者处理相关数据。像这样:

Im.create(imData).then(function(im) {
  Message.update(im.data.message, {im: im.data.id}).then(function(msg) {
    var senderGet = User.get(msg.data.im.sender).then(function(sender) {
      msg.data.im.sender = sender.data;
    });
    var receiverGet = User.get(msg.data.im.reciever).then(function(reciever) {
      msg.data.im.reciever = reciever.data;
    });
    $q.all([senderGet, receiverGet]).then(function() {
      if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
        $scope.messages.push(msg.data);
      } 
    });
  })
});

或者如果您认为它更具可读性的话,另一种选择:

Im.create(imData).then(function(im) {
  Message.update(im.data.message, {im: im.data.id}).then(function(msg) {
    var senderGet = User.get(msg.data.im.sender);
    var receiverGet = User.get(msg.data.im.reciever);
    $q.all([senderGet, receiverGet]).then(function(response) {
      msg.data.im.sender = response[0].data;
      msg.data.im.reciever = response[1].data;      
      if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
        $scope.messages.push(msg.data);
      } 
    });
  })
});