我正在开发一个聊天应用程序,它是服务器端的Node.js + MongoDB(Mongoose库),以及客户端的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);
此数据库包含一个包含所有用户的房间(即#34;我的酷房"用户:"迈克","乔"和"戴夫"。)
我想要做的是 - 每次用户想要进入Angular.js客户端的聊天室(有一些房间名称)时,我想:
我知道因为1,我总会有一个有一系列用户的房间。
这是我的Angular相关代码:(我不能在这里给出整个应用程序,因为它太大而且不相关。)
$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请求到达服务器的 - 所以我不认为问题就在那里。
答案 0 :(得分: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
});
}
答案 1 :(得分: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")
});
}
功能编程的经验法则是 - 总是返回。
因为调用promise的.then
方法会返回一个新的派生promise,所以很容易创建一个promise链。可以创建任意长度的链和,因为承诺可以通过另一个承诺来解决(这将进一步推迟其解析),可以在任何点暂停/推迟承诺的解决。连锁,链条。这使得实现强大的API成为可能。