IT story

angularjs에서 $ http 요청에서 응답이 올 때까지 기다리는 방법은 무엇입니까?

hot-time 2020. 9. 9. 20:14
반응형

angularjs에서 $ http 요청에서 응답이 올 때까지 기다리는 방법은 무엇입니까?


여러 페이지에서 RESTful 서비스의 일부 데이터를 사용하고 있습니다. 그래서 저는 그것을 위해 앵귤러 팩토리를 사용하고 있습니다. 따라서 서버에서 데이터를 한 번 가져와야했고, 정의 된 서비스로 데이터를 가져올 때마다 필요했습니다. 전역 변수와 같습니다. 다음은 샘플입니다.

var myApp =  angular.module('myservices', []);

myApp.factory('myService', function($http) {
    $http({method:"GET", url:"/my/url"}).success(function(result){
        return result;
    });
});

내 컨트롤러에서이 서비스를 다음과 같이 사용하고 있습니다.

function myFunction($scope, myService) {
    $scope.data = myService;
    console.log("data.name"+$scope.data.name);
}

내 요구 사항에 따라 잘 작동합니다. 그러나 여기서 문제는 웹 페이지에서 다시로드 할 때 서비스가 다시 호출되고 서버에 대한 요청이 있다는 것입니다. "정의 된 서비스"에 종속 된 다른 함수가 실행되는 사이에 "무언가"가 정의되지 않은 것과 같은 오류가 발생합니다. 그래서 서비스가로드 될 때까지 스크립트에서 기다리고 싶습니다. 어떻게 할 수 있습니까? 어쨌든 angularjs에서 그렇게합니까?


언제 완료 될지 모르는 비동기 작업에는 promise를 사용해야합니다. 약속은 "아직 완료되지 않았지만 미래에 예상되는 작업을 나타냅니다." ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise )

구현 예는 다음과 같습니다.

myApp.factory('myService', function($http) {

    var getData = function() {

        // Angular $http() and then() both return promises themselves 
        return $http({method:"GET", url:"/my/url"}).then(function(result){

            // What we return here is the data that will be accessible 
            // to us after the promise resolves
            return result.data;
        });
    };


    return { getData: getData };
});


function myFunction($scope, myService) {
    var myDataPromise = myService.getData();
    myDataPromise.then(function(result) {  

       // this is only run after getData() resolves
       $scope.data = result;
       console.log("data.name"+$scope.data.name);
    });
}

편집 : Sujoys와 관련하여 myFuction () 호출이 .then () 함수가 실행을 완료 할 때까지 반환되지 않도록해야 할 일은 무엇입니까?

function myFunction($scope, myService) { 
    var myDataPromise = myService.getData(); 
    myDataPromise.then(function(result) { 
         $scope.data = result; 
         console.log("data.name"+$scope.data.name); 
    }); 
    console.log("This will get printed before data.name inside then. And I don't want that."); 
 }

자, getData () 호출이 완료되는 데 10 초가 걸린다고 가정 해 보겠습니다. 그 시간에 함수가 아무 것도 반환하지 않으면 사실상 정상적인 동기 코드가되어 완료 될 때까지 브라우저를 멈 춥니 다.

With the promise returning instantly though, the browser is free to continue on with other code in the meantime. Once the promise resolves/fails, the then() call is triggered. So it makes much more sense this way, even if it might make the flow of your code a bit more complex (complexity is a common problem of async/parallel programming in general after all!)


for people new to this you can also use a callback for example:

In your service:

.factory('DataHandler',function ($http){

   var GetRandomArtists = function(data, callback){
     $http.post(URL, data).success(function (response) {
         callback(response);
      });
   } 
})

In your controller:

    DataHandler.GetRandomArtists(3, function(response){
      $scope.data.random_artists = response;
   });

I was having the same problem and none if these worked for me. Here is what did work though...

app.factory('myService', function($http) {
    var data = function (value) {
            return $http.get(value);
    }

    return { data: data }
});

and then the function that uses it is...

vm.search = function(value) {

        var recieved_data = myService.data(value);

        recieved_data.then(
            function(fulfillment){
                vm.tags = fulfillment.data;
            }, function(){
                console.log("Server did not send tag data.");
        });
    };

The service isn't that necessary but I think its a good practise for extensibility. Most of what you will need for one will for any other, especially when using API's. Anyway I hope this was helpful.


FYI, this is using Angularfire so it may vary a bit for a different service or other use but should solve the same isse $http has. I had this same issue only solution that fit for me the best was to combine all services/factories into a single promise on the scope. On each route/view that needed these services/etc to be loaded I put any functions that require loaded data inside the controller function i.e. myfunct() and the main app.js on run after auth i put

myservice.$loaded().then(function() {$rootScope.myservice = myservice;});

and in the view I just did

ng-if="myservice" ng-init="somevar=myfunct()"

in the first/parent view element/wrapper so the controller can run everything inside

myfunct()

without worrying about async promises/order/queue issues. I hope that helps someone with the same issues I had.

참고URL : https://stackoverflow.com/questions/18421830/how-to-wait-till-the-response-comes-from-the-http-request-in-angularjs

반응형