如何等待响应来自$ http请求,在angularjs?

ani*_*CSE 88 wait angularjs angularjs-service

我在多个页面中使用来自RESTful服务的一些数据.所以我正在使用棱角分明的工厂.因此,我需要从服务器获取一次数据,并且每次我使用该定义的服务获取数据.就像一个全局变量.这是样本:

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

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

在我的控制器中,我使用此服务:

function myFunction($scope, myService) {
    $scope.data = myService;
    console.log("data.name"+$scope.data.name);
}
Run Code Online (Sandbox Code Playgroud)

根据我的要求,它对我来说很好.但问题是,当我在我的网页上重新加载时,服务将再次被调用并请求服务器.如果在某些其他函数执行之间依赖于"已定义的服务",它会给出错误,例如"某事"是未定义的.所以我想在我的脚本中等待服务加载.我怎样才能做到这一点?无论如何在angularjs中有这样做吗?

mik*_*kel 146

您应该使用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);
    });
}
Run Code Online (Sandbox Code Playgroud)

编辑:关于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."); 
 }
Run Code Online (Sandbox Code Playgroud)

好吧,我们假设对getData()的调用需要10秒才能完成.如果函数在那段时间内没有返回任何内容,它将有效地成为正常的同步代码,并且会挂起浏览器直到它完成.

随着承诺立即返回,浏览器可以在此期间继续使用其他代码.一旦promise解析/失败,就会触发then()调用.因此,这种方式更有意义,即使它可能会使代码流更复杂(毕竟复杂性是异步/并行编程的常见问题!)

  • @mikel:我还有另一个问题.你的myFuction()调用将立即返回,但是这个promise .then()将稍后调用.我需要做什么才能使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("这将在data.name之前打印出来.然后我不希望这样."); }` (7认同)
  • 这解决了我的问题!对于其他任何人,我有一个需要来自ajax调用的数据的下拉列表,因此在创建范围时,数据不可用.通过此延迟,可以指定范围以使数据来自ajax调用. (2认同)

Rau*_*mez 13

对于刚接触此人的人,您也可以使用回调,例如:

在您的服务中:

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

   var GetRandomArtists = function(data, callback){
     $http.post(URL, data).success(function (response) {
         callback(response);
      });
   } 
})
Run Code Online (Sandbox Code Playgroud)

在你的控制器中:

    DataHandler.GetRandomArtists(3, function(response){
      $scope.data.random_artists = response;
   });
Run Code Online (Sandbox Code Playgroud)