为什么在Angular服务中使用$ http时返回promise和数据?

时间:2015-02-26 17:07:08

标签: javascript angularjs angular-promise angularjs-http

我经常在网上看到有关Angular服务的教程和片段,以便进行$ http调用,同时返回$ http承诺和一些数据。如果将promise返回给控制器,那么返回服务中的数据有什么意义呢?我甚至不知道它归还的地方。这是我的意思的一个例子:

 // Function of MyStuffService:
 function getStuff() {
    return $http.get('/api/stuff')
        .success(function(data) {
            // Why return data here? How could I even get this returned value?
            return data;
        })
        .error(function(data) {
            console.error(data);
        });
}

// Controller:
function getStuff() {
    MyStuffService.getStuff()
        .success(function(data) {
            $scope.stuff = data;
        })
}

我不能只重写我的服务功能:

 // Function of MyStuffService:
 function getStuff() {
    return $http.get('/api/stuff')
        .error(function(data) {
            console.error(data);
        });
}

让控制器从返回的承诺中获取数据?我觉得我在这里不懂东西。非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

.then中返回的数据可用于下一个链式.then处理程序,这是您最终用于获取数据的处理程序。

.success只传达了$http.get的原始承诺。从.success返回数据并没有做任何事情。

所以,如果你有:

 function getStuff() {
    return $http.get('/api/stuff')
        .success(function(data) {
            // do something with data. returning doesn't do anything
        })
        .error(function(data) {
            console.error(data);
        });
};
你可以在控制器中执行

getStuff().then(function(response){
  $scope.data = response.data; // this is the data available from `$http.get`
}

答案 1 :(得分:1)

您引用的教程不会在成功处理程序中返回数据,而是在then处理程序中返回result.data。然后返回生成新链式承诺的那个。这将删除.then。

中通常存在的http请求数据

为什么要这么麻烦?

使用.then代替.success的原因是为了将来验证。 .success不是承诺的一部分,它特定于$ http。如果您决定稍后从另一个异步源(websockets,webworkers)获取数据,那么当您返回的promise不再具有成功处理程序时,您的代码将会中断。

通过使其始终返回。然后,确保您的服务被充分抽象化。

答案 2 :(得分:0)

如果您需要在将数据发送到控制器之前进行一些处理,通常会这样做。

但在这种情况下,我同意由于没有数据处理,因此无需在服务中解决承诺。

在这种情况下,我只需将服务方法重写为: -

function getStuff() {
   return $http.get('/api/stuff');
}

如果在将数据返回控制器之前必须进行一些处理,我倾向于使用$ q,如下所示。

function getStuff() {
    var defer = $q.defer();
    $http.get('/api/stuff')
        .then(function(data) {
            // some processing
            defer.resolve(processedData);
        }, function(error) {
            defer.reject(error);   
        });
        return defer.promise;
}