2016-12-31 55 views
3

我工作的聊天应用程序,它是在服务器端的Node.js + MongoDB的(猫鼬库),并Angular.js在客户端。的Node.js + Angular.js有望同步问题

我有一个数据库集合(MongoDB的)的房间(在应用程序中所有的房间),它看起来像这样:

// ------- creating active_rooms model ------- 
var active_rooms_schema = mongoose.Schema({ 
    room_name: String, 
    users: [String] 
}); 
var active_rooms = mongoose.model('active_rooms', active_rooms_schema); 

该数据库包含其所有用户的房间(即“我的室内阴凉处“与用户:”迈克“,”乔“和”戴夫“)。

我想要做的是 - 每一个用户想在在我的Angular.js客户端聊天室(有一些房间名)的时候,我想:

  1. 创建,如果房间是不存在
  2. 推该用户进入房间的用户阵列。

我知道,因为1,我将永远有一个用户数组的空间。

这是我的角相关代码:(我不能在这里给整个应用,因为它的方式过大和不相关的。)

$scope.enterRoom = function(info) { 
    $q.when(create_room_if_not_exists($scope.room)).then(add_user_to_room($scope.name, $scope.room)); 
    $location.path("chat"); 
} 


var create_room_if_not_exists = function(room_name) { 
    var deferred = $q.defer(); 
    is_room_already_exists({ 
     'name': room_name 
    }).then(function(response) { 
     if (!response.data.is_room_exists) { 
      register_room({ 
       'name': room_name 
      }); 
      console.log("room: " + room_name + ", was created"); 
      deferred.resolve(); 
     } 
    }, function(error) { 
     deferred.reject(error.data); 
    }); 
    return deferred.promise; 
} 

var add_user_to_room = function(user_name, room_name) { 
    console.log(user_name) 
    add_user_to_room_request({ 
     'user_name': user_name, 
     'room_name': room_name 
    }); 
} 

var is_room_already_exists = function(info) { 
    return $http({ 
     url: '/is_room_already_exists', 
     method: 'POST', 
     data: info 
    }); 
} 

var add_user_to_room_request = function(info) { 
    $http({ 
     url: '/add_user_to_room', 
     method: 'POST', 
     data: info 
    }); 
} 

var register_room = function(info) { 
    return $http({ 
     url: '/register_room', 
     method: 'POST', 
     data: info 
    }); 
} 

什么情况是,第二个动作一日一之前发生。当我在控制台上打印日志时,我看到了这一点,但我不知道为什么。

这些行动都到达通过HTTP请求到服务器 - 所以我不认为这个问题是存在的。

+1

如图所示,两个XHR将链接。位置路径将在两个XHR完成之前发生变化。当你说“第二次行动发生在第一次行动之前”时,你是否谈论XHR在XHR完成之前没有链接或位置改变? – georgeawg

+0

我正在谈论XHR不链接 – Matoy

+1

注意:您可能想尝试简单地将用户添加到房间,然后只在第一次呼叫失败时尝试创建房间。它将完全消除对“is_room_already_exists”函数的需求。 – idbehold

回答

1

我说的是XHR时无法链接

与链问题的常见原因是没有承诺返回链:

var add_user_to_room = function(user_name, room_name) { 
    console.log(user_name) 
    //add_user_to_room_request({ 
    return add_user_to_room_request({ 
    //^^^^^^ ----- be sure to return returned promise 
     'user_name': user_name, 
     'room_name': room_name 
    }); 
} 

如果链接处理得当,$q.defer是没有必要:

var create_room_if_not_exists = function(room_name) { 
    //var deferred = $q.defer(); 
    //is_room_already_exists({ 
    return is_room_already_exists({ 
    //^^^^^^ --- be sure to return derived promise 
     'name': room_name 
    }).then(function(response) { 
     if (!response.data.is_room_exists) { 
      console.log("room: " + room_name + ", to be created"); 
      //register_room({ 
      return register_room({ 
      //^^^^^^ ----- return promise to further chain 
       'name': room_name 
      }); 
      //deferred.resolve(); 
     } else { 
      return room_name; 
      //^^^^^^ ----- return to chain data 
     }; 
    }, function(error) { 
     //deferred.reject(error.data); 
     throw error; 
     //^^^^^ ------- throw to chain rejection 
    }); 
    //return deferred.promise; 
} 

如果正常返回一个承诺,$q.when是没有必要的:

$scope.enterRoom = function(info) { 
    //$q.when(create_room_if_not_exists($scope.room)) 
    // .then(add_user_to_room($scope.name, $scope.room)); 
    return create_room_if_not_exists($scope.room) 
     .then(function() { 
      return add_user_to_room($scope.name, $scope.room)); 
     }).then(function() 
      $location.path("chat") 
     }); 
} 

拇指的函数式编程的规则是 - 总有返回

由于调用承诺的.then方法会返回一个新的派生承诺,因此很容易创建一个承诺链。它可以创建任何长度和的链的许诺可与另一承诺(这将进一步推迟其分辨率)来解决,所以能够暂停/在链中的任何点推迟承诺的分辨率。这使得实现强大的API成为可能。

- AngularJS $q Service API Reference - Chaining Promises

1

试试这个:

$scope.enterRoom = function (info) { 
    return create_room_if_not_exists($scope.room)).then(function(){ 
    return add_user_to_room_request({ 'user_name': $scope.name, 'room_name': $scope.name }); 
    }).then(function(){ 
    $location.path('chat'); 
    }); 
} 


var create_room_if_not_exists = function (room_name) { 
    var deferred = $q.defer(); 
    return is_room_already_exists({ 'name': room_name }).then(function (response) { 
     if (!response.data.is_room_exists) { 
      console.log("room: " + room_name + ", is being created"); 
      return register_room({ 'name': room_name }); 
     } 
     return response; 
    }) 
} 

    var is_room_already_exists = function (info) { 
     return $http({ 
      url: '/is_room_already_exists', 
      method: 'POST', 
      data: info 
     }); 
    } 

var add_user_to_room_request = function (info) { 
      return $http({ 
       url: '/add_user_to_room', 
       method: 'POST', 
       data: info 
      }); 
     } 

    var register_room = function (info) { 
      return $http({ 
       url: '/register_room', 
       method: 'POST', 
       data: info 
      }); 
     } 
+0

谢谢,但仍然没有运气。我添加了日志记录到客户端,我看到这个顺序: is_room_already_exists, add_user_to_room_request, register_room。它应该是: is_room_already_exists register_room add_user_to_room_request – Matoy

+1

@Matoy根本不可能用我提供的代码。 – idbehold

+1

你是对的。抱歉。你的解决方案是正确的我的代码没有在服务器上正确刷新。谢谢! – Matoy