2015-08-24 87 views
1

所以我正在一个项目,我有一个数据集,我必须检索数据集的各种统计数据取决于用户输入从服务器检索数据。解开承诺从HTTP服务返回

我试图设置一个AngularJS服务,它具有返回给定数据点上各种信息的各种方法。

这里是从服务的公共方法:

function test() { 
    return $http.get('blahblah.api.../datapoint1') 
    .success(function(data) { 
     console.log(data.name); 
     return data.name; 
    }); 
} 

下面是相关部分从控制器:内

self.data = service.test(); 
console.log(self.data); 

有趣的是,所述的console.log(data.name) http调用的成功正是我想要的。给定数据点的名称。 但是,其范围外的console.log(self.data)为我提供了原始承诺对象。我用来发送超出“成功”范围的信息的任何方法都为我提供了一个承诺对象。为什么是这样?有什么方法可以解决这个问题吗?处理控制器中的错误处理似乎非常低效。

回答

0

没有办法使该服务同步,你应该总是使用承诺。

试试这个:

function test() { 
    return $http.get('blahblah.api.../datapoint1') 
    .success(function(data) { 
     console.log(data.name); 
     return $q.resolve(data.name); 
    }); 
} 

然后将此:

service.test().then(function (name) { 
    self.data = name; 
    console.log(self.data); 
}) 

编辑

关于为什么你得到一个承诺认为你的代码是一样的以下:

function something(data) { 
    console.log(data.name); 
    return data.name; 
} 

function test() { 
    return $http.get('blahblah.api.../datapoint1') 
    .success(something); 
} 

您的代码将调用的结果返回给成功,这确实是一个承诺。

+0

我明白了。谢谢!任何具体原因,为什么它不能同步?或者解释为什么的链接?我假设有这样的理由需要这样做。 – Vangogh500

+0

当然:http://stackoverflow.com/questions/13088153/how-to-http-synchronous-call-with-angularjs。另外请注意,javascript是按定义异步的,所以即使它是可能的(最好是使用Jquery或普通的旧XHR,但它是一个不推荐的行为),它根本不值得推荐 –

2

您不会为您的功能创建新的承诺。

看看你的test函数。看看你有两个回报?第一次,您返回$http.get函数,这是一个承诺,但承诺可以解析为success函数。你从成功函数返回的东西并不能解决这个承诺 - 它已经在成功函数中解决了。

相反,您需要为您的服务功能创建新的承诺并将其返回给您的应用。

这里是你如何组织你的要求

function test() { 
    // Setup a promies for this function to return 
    var deferred = $q.defer() 

    $http.get('blahblah.api.../datapoint1') 
    .success(function(data) { 
     console.log(data.name); 

     // Return our data to use in our app 
     deferred.resolve(data); 
    }); 

    // Return the promise 
    return deferred.promise 
} 

实施

service.test().then(function(data){ 
     self.data = data 
     console.log(self.data.name) //should be the same as in your service 
}); 

注意,您需要在您的服务$q注射器。

+0

完全没有理由创建第二个承诺。 $ http已经返回一个。 –

+0

这是不真实的:http://www.mattgreer.org/articles/promises-in-wicked-detail/#chaining-promises –

+0

只是好奇你为什么会做出新的承诺?这不仅仅意味着要处理更多的东西吗?为什么不只是从http.get()返回原始的承诺。或者我们这样做,以便我们也可以处理服务中的错误处理以及控制器? – Vangogh500

1

不,这是不可能得到该值以任何有意义的方式外范围,直到之后的承诺已得到解决。您必须从回调中访问它。就错误处理而言,这当然可以由您的服务来处理。

function test() { 
    return $http.get('blahblah.api.../datapoint1') 
    .then(function(response) { 
     console.log(response.data.name); 
     return response.data.name; 
    }).catch(function (e) { 
     // error handling... 
    }); 
} 
self.data = ''; // default value 
service.test().then(function (name) { 
    self.data = name; 
    console.log(self.data); // correct value 
}); 
console.log(self.data); // still default value 

我建议从有利于.then().catch()使用.success().error()移开,前两次都被弃用在最近版本的AngularJS的。