sincrono - ¿Cómo esperar hasta que la respuesta provenga de la solicitud $ http, en angularjs?




ng attr title (3)

Deberías usar promesas para operaciones asíncronas en las que no sabes cuándo se completarán. Una promesa "representa una operación que aún no se completó, pero que se espera para el futuro". ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise )

Un ejemplo de implementación sería como:

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

Editar: Con respecto a Sujoys comenta que Qué debo hacer para que la llamada myFuction () no regrese hasta que la función .then () termine la ejecución.

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."); 
 }

Bueno, supongamos que la llamada a getData () tardó 10 segundos en completarse. Si la función no devolvía nada en ese momento, se convertiría efectivamente en código síncrono normal y colgaría el navegador hasta que se completara.

Sin embargo, con la promesa de regresar al instante, el navegador puede continuar con otros códigos mientras tanto. Una vez que la promesa se resuelve / falla, se activa la llamada a continuación (). Por lo tanto, tiene mucho más sentido de esta manera, incluso si puede hacer que el flujo de su código sea un poco más complejo (¡después de todo, la complejidad es un problema común de la programación asincrónica / paralela en general!)

Estoy usando algunos datos que provienen de un servicio RESTful en varias páginas. Así que estoy usando fábricas angulares para eso. Por lo tanto, solicité que los datos se obtuvieran una vez del servidor y cada vez que obtengo los datos con ese servicio definido. Al igual que las variables globales. Aquí está la muestra:

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

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

En mi controlador estoy usando este servicio como:

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

Funciona bien para mí según mis requisitos. Pero el problema aquí es que, cuando volví a cargar en mi página web, se llamará nuevamente al servicio y se solicitará el servidor. Si entre alguna otra función se ejecuta que depende del "servicio definido", está dando el error como "algo" no está definido. Así que quiero esperar en mi script hasta que el servicio esté cargado. ¿Cómo puedo hacer eso? ¿Hay alguna forma de hacer eso en angularjs?


Estaba teniendo el mismo problema y ninguno si esto funcionó para mí. Esto es lo que sí funcionó ...

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

    return { data: data }
});

y luego la función que lo usa es ...

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.");
        });
    };

El servicio no es necesario, pero creo que es una buena práctica para la extensibilidad. La mayor parte de lo que necesitarás para uno será para cualquier otro, especialmente cuando uses las API. De todos modos, espero que esto haya sido útil.


para las personas que no conozcan esto, también pueden usar una devolución de llamada, por ejemplo:

En su servicio:

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

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

En tu controlador:

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




angularjs-service