Promise callback not called in Angular JS

2019-01-23 16:51发布

问题:

If I call connect from doStuff, I get the message that "the socket is connected", but the callback is not called. What am I missing here?

 $scope.connect = function() {
    var defer = $q.defer();
    ws = new WebSocket("ws://server.com:port");
    ws.onopen = function(){  
        console.log("Socket connected");
        defer.resolve("socket connected");
    };
    return defer.promise;
}

$scope.doStuff = function() {
    $scope.connect().then(function(data) {
        console.log("And we're off!", data);
    });
}

回答1:

In AngularJS promise results are propagated asynchronously, inside a $digest cycle. So, your callback function registered with then() will only be called upon entering a $digest cycle.

So, when your socket connects, we are in a digest cycle. then() creates a new promise, but the results of that then() will not be propagated until the next digest cycle, which never comes (because there is no $timeout, or $http, or DOM event to trigger one). As @Ajay just posted, if you add $scope.$apply(), it will cause a digest cycle and you'll see the results.



回答2:

You should be using $scope.$apply() please find the below working code

function formctrl($scope,$q,$timeout) {
            $scope.connect = function () {
                var defer = $q.defer();
                var ws = new WebSocket("ws://echo.websocket.org");
                ws.onopen = function (evt) {
                    defer.resolve("socket connected");
                    $scope.$apply();
                }
                return defer.promise;
            }

            $scope.raise = function () {
                $scope.connect().then(function (data) {
                    alert(data);

                });
            }


        }