2016-06-28 55 views
11

我目前使用$ Q服务的角度来进行API调用是这样的:

var deferred = $q.defer(); 
$http.get(config.apiHost + details.url) 
    .success(function (data) { 
     deferred.resolve(data); 
    }).error(function (msg) { 
     deferred.reject(msg); 
    }); 
return deferred.promise; 

但我们也还可以用这种方法不使用$问:

return $http.get(config.apiHost + details.url) 
    .success(function (data) { 
     return data; 
    }).error(function (msg) { 
     return msg; 
    }); 

和$ HTTP本身返回的诺言,我也可以用更简单的方法:

$http.get(config.apiHost + 'posts') 
     .success(function (data) { 
      console.log(data) 
     }).error(function (msg) { 
      console.log(msg); 
     }); 

那么所有这些特别是$ q和$ http之间有什么区别,因为两者都返回promise,并且都是异步?角度提供$ q的一些额外的功能? 我无法找到任何好的答案。

+0

您可以使用$ q返回其他异步操作的承诺。 $ http从AJAX调用中返回一个承诺。 – Hoyen

+0

其他操作如? –

+0

就像阅读文件或如果您需要使用$ timeout – Hoyen

回答

2

$q主要只用于兼容与默认情况下不支持的承诺,当你不能依靠本机实现Promise库(例如 - 在旧的浏览器IE9一样)。否则没有理由(对你)使用它。例如,如果你想做一个基于承诺的$timeout$http本身使用$q这些确切的原因。

不像其他什么(因为删除)答案建议你做需要才能使用$q“存储”的$http承诺的结果。我不建议存储所有的承诺(因为这往往会导致意大利面条代码),但是如果你必须绝对做到这一点,你可以存储从$http得到的承诺;承诺只能执行一次。

在承诺解决/拒绝后传递给then的任何函数都将在下一个计时器上解决,而无需重新调用创建承诺的原始操作 - IOW,承诺的结果在内部被记忆那个对象。

还要注意的是承诺链,这是升技超出范围的这个答案,但它本质上意味着下面的代码片段是等价的

function legacyGet() { 
    const deferred = $q.defer() 
    $http.get('http://www.google.com') 
    .then((response) => deferred.resolve(Object.assign(response, {foo: bar})) 
    .catch((error) => deferred.reject(error)) 
    return deferred.defer 
} 

function modernGet() { 
    return $http.get('http://www.google.com') 
    .then((response) => Object.assign(response, {foo: bar})) 
} 

总结:你的标题是错误的。我们不喜欢使用$ q,我们只是谨慎地使用它。更喜欢使用ES6 Promise,除非你需要支持没有它的浏览器你不能使用polyfill。

7

$http使用$q,第一个例子是多余的,第二个例子也是多余的。你只需要返回承诺,$http.get回报:

return $http.get(config.apiHost + details.url); 

以上是与您的第一段代码。

另外,return msgdeferred.reject(msg)不一样。相当于将throw msgreturn $q.reject(msg)

另一个要注意的是,successerror是非标准的,要使用thencatch

+0

我不会说'成功'和'错误'是“非标准”,只是弃用:https://docs.angularjs.org/ api/ng/service/$ http – pulse0ne

+1

@ pulse0ne他们*是非标准的,如果你在谈论A +承诺规范 –

+0

@DanPantry啊,是的,我错误地认为你指的是$ http服务。关于规范,这是非标准的,几乎可以肯定为什么角度人物不赞成它。 – pulse0ne

0

在角度上,大多数服务仅返回承诺,但有些情况下您希望使用$q创建自己的延迟对象。

案例1

当您正在使用不支持承诺库或创建您自己的功能,并希望返回一个承诺。

案例2

当您正在使用的默认返回一个承诺任何结构,但要返回基于一些在某些条件下独立的承诺。

:在角$http回报承诺只,但现在如果你想,如果这个承诺的响应包含一个特定的值,那么只有你想返回解决否则返回失败,那么你需要创建自己的deffered object和需要根据$http响应返回的值来解决或失败它。

+0

你不需要那样做。承诺链。你可以简单地执行'$ http.get()。then(...)'和'then'返回的值将被传递给链中的下一个.then。无需为此使用自己的延期对象。 –

+0

我在谈论$ http..like的反应,如果你想要的话,如果响应包含一定的价值而不是解决承诺或只是拒绝。 –

+1

这个答案不准确,正在描述共同推迟反模式 – charlietfl

相关问题