【问题标题】:Angularjs chat with strange pollingAngularjs 用奇怪的轮询聊天
【发布时间】:2015-11-23 19:43:56
【问题描述】:

我在 angularjs 中创建了一个与前端的简单聊天。它在左侧有一个简单的索引,包含用户进行的所有对话,带有 show(chat_id) 操作,在右侧打开聊天本身,使用轮询来获取新消息。

执行所述功能的控制器的主要部分:

$scope.show = function(id) {
  $scope.chat = [];
  $scope.currentConversation = id;
  var poll = function(){
    conversation.get(id).then( function( conversation ) {
      $scope.chat = conversation.data.messages;
      $scope.form = true;
      $timeout(function() {poll()}, 5000)
    });
  }
  poll(); 
}

我的问题是,每当我快速单击两个不同的对话时,例如 show(1)show(2),我都会得到一个奇怪的行为,它会通过轮询操作从对话 1 来回切换。

这是 Angular 正在发出的获取请求。

对于上下文化,这里是简单的聊天 UI

【问题讨论】:

  • $timeout(function() {poll()}, 5000) 应该做什么?它调用 poll() 没有任何参数。这是你的真实代码吗?如果没有,请发布您的真实代码。
  • 是的,这是真正的代码。它应该每 5 秒从数据库中获取所有消息,以防有新消息。
  • 但是 poll() 需要一个参数。而你没有通过任何。即使你通过了一个,一旦你调用 show(1),这段代码就会每 5 秒刷新一次聊天。调用 show(2),它会添加 另一个 递归刷新,不会替换之前的。
  • 哦,我错误地将 poll 的论点留在那里,我在问题上更正了,但同样的行为发生了
  • 现在最后一行使用它不期望的参数调用该函数。修改您的代码,直到它有意义并重现问题,然后复制并粘贴该真实代码。

标签: angularjs


【解决方案1】:

正如我在评论中所说,每次调用 show() 时,都会启动一个新的递归循环,每 5 秒轮询一次具有给定 id 的对话。

因此,如果您点击 4 个对话(1、2、3 和 4),您最终会每 5 秒刷新一次对话 1,每 5 秒再刷新一次对话 2,依此类推。

这不是你想要的。显示对话后,您只想刷新那个对话,而不是其他对话。

因此,您可以使用以下代码在每次调用 show() 时取消先前的超时,并在收到响应时验证显示的对话 ID 是否正确:

var timer;
$scope.show = function(id) {
  $scope.chat = [];
  $scope.currentConversation = id;
  if (timer) {
    $timeout.cancel(timer);
  }
  var poll = function(){
    conversation.get(id).then( function( conversation ) {
      if ($scope.currentConversation == id) {
        $scope.chat = conversation.data.messages;
        $scope.form = true;
        timer = $timeout(function() {poll()}, 5000);
      }
    });
  }
  poll(); 
}

【讨论】:

  • 像魅力一样工作!谢谢
【解决方案2】:

您可能希望在内部函数中进行检查,以确保 $scope.currentConversation === id。这将防止它失去上下文。我的猜测是,这是您在第一次点击之前点击的竞争条件 conversation.get(id) 回来了。

$scope.show = function(id) {
  $scope.chat = [];
  $scope.currentConversation = id;
  var poll = function(){
    conversation.get(id).then( function( conversation ) {
      if ($scope.currentConversation !== id) return; // Prevent the race condition
      $scope.chat = conversation.data.messages;
      $scope.form = true;
      $timeout(function() {poll()}, 5000)
    });
  }
  poll(); 
}

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 2010-09-07
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多