for循环中的异步变量

时间:2016-08-03 03:58:27

标签: javascript firebase asynchronous firebase-realtime-database nosql

我正在努力向Chrome扩展程序添加通知,以便用户可以相互聊天。每个用户都有一个chats部分,列出了他们所在的所有聊天室,以及他们看到的最后一条消息。为了检查消息是否在他们离开时发送,我试图遍历他们所在的聊天室,并查看最后发送的消息是否在他们看到的最后一条消息被添加后添加到数据库中。

这是我的代码,我正在使用名为firebase的noSQL数据库:

var checkNotifications = function(user){
   var notification = false;
   firebase.database().ref('users/'+user+'/chats').once('value', function(snapshot){
      for (var chat in snapshot.val()){
         var lastMessage = snapshot.val()[chat];
         firebase.database().ref('chats/'+chat+'/msgs').once('value', function(snap){
            if (Object.keys(snap.val())[0] > lastMessage){
               notification = true;    // Message is newer than their last seen message
            }
         });
      }
   });
}

我遇到的问题是,在第二次数据库调用之前从for循环中当前正在查看的聊天室返回消息时,for循环已经移动并更新变量lastMessage,所以该变量最终会从链接下方的聊天室中保留最后一条消息。

有没有办法减少异步,以便变量lastMessage对for循环中的每一步具有相同的值?

2 个答案:

答案 0 :(得分:1)

  

要检查消息是否在他们离开时发送,我正在尝试   循环浏览他们所在的聊天室并查看最后一条消息   发送后,他们看到的最后一条消息被添加到数据库中   加入。

transactions选择一个函数并且是适当的工具。

  

处理可能被并发损坏的数据时   修改,如增量计数器,您可以使用事务   操作。您可以为此操作提供更新功能和   可选的完成回调。更新功能接受当前   作为参数的数据状态,并返回新的所需状态   想写。如果另一个客户端之前写入该位置   成功编写新值后,将调用更新函数   再次使用新的当前值,并重试写入。   例如,在示例社交博客应用中,您可以允许用户对帖子进行加星标记和取消加星标,并跟踪帖子收到的星标数,如下所示:

function toggleStar(postRef, uid) {
  postRef.transaction(function(post) {
    if (post) {
      if (post.stars && post.stars[uid]) {
        post.starCount--;
        post.stars[uid] = null;
      } else {
        post.starCount++;
        if (!post.stars) {
          post.stars = {};
        }
        post.stars[uid] = true;
      }
    }
    return post;
  });
}

答案 1 :(得分:1)

这应该有效。它在闭包中捕获变量:(function(){ ... })();

var checkNotifications = function(user){
    var notification = false;
    firebase.database().ref('users/'+user+'/chats').once('value', function(snapshot){
        for (var chat in snapshot.val()){
            (function(){
                var lastMessage = snapshot.val()[chat];
                firebase.database().ref('chats/'+chat+'/msgs').once('value', function(snap){
                    if (Object.keys(snap.val())[0] > lastMessage){
                        notification = true;    // Message is newer than their last seen message
                    }
                });
            })();
        }
    });
}

或者这个:

var checkNotifications = function(user){
    var notification = false;
    firebase.database().ref('users/'+user+'/chats').once('value', function(snapshot){
        var func = function(lastMessage) {
            firebase.database().ref('chats/'+chat+'/msgs').once('value', function(snap){
                if (Object.keys(snap.val())[0] > lastMessage){
                    notification = true;    // Message is newer than their last seen message
                }
            });
        };
        for (var chat in snapshot.val()){
            func(snapshot.val()[chat]);
        }
    });
}