繁体   English   中英

Node.js + Angular.js承诺同步问题

[英]Node.js + Angular.js promises sync issue

我正在开发一个聊天应用程序,它是服务器端的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);

这个数据库包含一个房间及其所有用户(即“我的酷房间”,用户:“迈克”,“乔”和“戴夫”)。

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

  1. 如果房间不存在,请创建房间
  2. 将该用户推送到会议室的用户阵列中。

我知道因为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请求到达服务器 - 所以我认为问题不存在。

尝试这个:

$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
            });
        }

我说的是没有链接的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成为可能。

- AngularJS $ q服务API参考 - 链接承诺

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM