2014-07-18 2 views
1

비동기 함수의 반환 값에 대한 조사를 설정하려고하지만 무한 다이제스트 루프를 계속 실행하려고합니다. 여기에 훨씬 더 자주 처음보다 호출되는 내 $ 시계

$scope.$watch(function(){ 
    var friendsCount = PublicUserData().then(function(data){ 
     console.log(data.length); 
     return data.length; 
    }); 
    return friendsCount; 
    }, function(newValue, oldValue) { 
    console.log("change"+ newValue); 
    }); 

내가 모두 console.log가 호출되는 크롬 콘솔에서 볼 수 있지만 (콜백)에 두 번째입니다.

.factory('PublicUserData', function($http, $q){ 
    return function(){ 
    var defer = $q.defer(); 
    $http.get('/api/v1/users/').then(function(data){ 
     defer.resolve(data.data.users); 
    }) 
    return defer.promise; 
    } 
}) 

$watch의 외부 $ 범위로 시계 식을 설정처럼, 몇 가지를 시도했다, 그러나 그것은 오히려 공장의보다, 공장의 코드를 반환 끝 :

PublicUserData$q 사용 반환 값.

$watch을 사용하여 약속을 구현할 수 있습니까? 아니면 다른 것을 사용해야합니까?

답변

6

정말 정말 정말로 $watch에서 AJAX 요청을하고 싶지 않습니다. 정말.

각도 사용은 더티 검사이며 $watch 함수는 $scope에 변경 될 때마다 반복적으로 호출됩니다. 작동 시키면 서버를 스팸하는 동안 응용 프로그램의 성능이 완전히 중지됩니다.

당신이하려고하는 것은 얼마나 많은 친구가 로그인했는지 보여주는 카운터가있는 것 같습니다. 이 문제는 서버 이벤트 나 폴링 메커니즘을 사용하면 더 쉽게 해결할 수 있습니다. 폴링은 가장 쉬운 방법입니다. 서버를 폴링합니다

$interval(function() { 
    PublicUserData().then(function(data) { 
     $scope.data.friendsCount = data.length; 
    }); 
}, 1000); 

초마다 (아마 잔인한,하지만 $watch에 그것을하는 것보다 훨씬 덜 자주 인)과 올바른으로 $scope를 업데이트

대신 같은 것을 고려 값.

+1

아 당신은 당신이 공장에서이 작업을 수행하고 단순한 범위 변수를 사용할 수 있습니다 (시간 제한 또는 간격을 사용하는지 여부) 폴링합니다. 왜 다이제스트 루프를 일으키는 지 알 수 없었습니다. 이 접근법에 대한 또 다른 방법, 환호에 대한 아이디어를 나에게 주었다. – user2936314

+2

@ user2936314 웹 소켓을 제공하거나 응용 프로그램에 장기간 통신 할 수있는 솔루션을 확인하십시오. 폴링 대신 서버에서 정보를 푸시 할 수 있습니다.예를 들어 우리는 Java 기반 앱에서'Atmosphere'를 사용하고 있습니다. – akn

2

이미 약속이있는 경우 왜 $ watch를해야합니까?

PublicUserData().then(function(data){ 
    $scope.friendsCount = data 
}); 

당신이 간격 최적의 성능에서 실행해야하는 경우는 간격

callForFriendsCount = function() { 
    PublicUserData().then(function(data){ 
    $scope.friendsCount = data 
    $timeout(callForFriendsCount, 1000) 
    }); 
} 

$ 제한 시간이 더 나은 아이디어 인 $ 제한 시간을 제공하기 때문에 어떤 경우에도 이전의 호출은 이상 1,000 밀리 걸릴 경우 $ timeout을 사용하면 가장 최근의 호출과 중복됩니다.

2

ivarni의 훌륭한 대답에 대한 또 다른 비슷한 해결책을 제시하기 만하면됩니다.

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope, PublicUserData) { 

    $scope.pollData = PublicUserData.pollData; 

}); 


app.factory('PublicUserData', function($http, $q, $interval){ 


    var srv = { 
    pollFn: function() { 
     srv.stopInterval = $interval(function() { 

     srv.pollData.friendCount++; 
     console.log('polled'); 

     }, 1000); 
    }, 
    pollData: {friendCount: 0, other: {}}, 
    stop: function() { 
     $interval.cancel(srv.stopInterval); 
    } 

    } 

    srv.pollFn(); 

    return srv; 
}); 

데모 : 내가 볼 http://plnkr.co/edit/0467sypyeg0Wpdr4302k?p=preview

관련 문제