Angular HttpPromise:`success` /`error`方法和`then`的参数之间的区别


177

根据AngularJS doc,调用$http返回以下内容:

返回带有标准then方法和两个http特定方法的promise对象:successerror。所述然后方法有两个参数一成功以及错误回调将与响应对象被调用。的成功错误的方法采取一个参数-一当请求成功或失败分别将被调用的函数。传递给这些函数的参数是传递给then方法的响应对象的结构化表示。

除了response在一种情况下对象被破坏的事实之外,我没有得到

  • 成功/错误回调作为参数传递 promise.then
  • 回调作为promise 的promise.success/ promise.error方法的参数传递

有没有?传递看似相同的回调的这两种不同方式的意义何在?

Answers:


156

注意:这个答案实际上是不正确的。正如下面的评论所指出的那样,success()确实返回了原始的诺言。 我不会改变 并留给OP进行编辑。


两者之间的主要区别在于,.then()调用返回一个promise(由回调返回的值解决),而.success()注册回调是一种更传统的方式,并且不返回promise。

基于承诺的回调(.then())可轻松实现承诺链(进行一次呼叫,解释结果,然后再进行另一次呼叫,解释结果,进行另一次呼叫等)。

.success()当您不需要链接调用或不需要使用promise API(例如,在路由中)时,该方法是一种简化的便捷方法。

简而言之:

  • .then() -promise API的全部功能,但更详细
  • .success() -不返回承诺,但提供更方便的语法

44
另一个很大的不同是,then回调需要一个参数-响应-而successerror采取的应对为arguments--的各个组件datastatusheader,和config
Michelle Tilley

1
@BrandonTilley完全正确,但是问题的作者已经弄清楚了,所以我不觉得我需要在这里重复一遍。
pkozlowski.opensource,

45
尽管文档中没有明确说明,但我们可以推断出该.success()方法返回了原始的$ http promise对象,因为该链接$http(...).success(...).error(...)是可能的。如果在合理的$http(...).error(...).success(...)情况下也可以进行逆运算,则还.error()应该返回原始的Promise对象。的区别 .then()在于,它返回了新的承诺。
甜菜根-甜菜根,

2
来自$ http服务的angular.js的源代码: promise.success = function(fn) { promise.then(function(response) { fn(response.data, response.status, response.headers, config); }); return promise; };
Alex Che,

6
请注意,它success已被弃用。来自docs.angularjs.org/api/ng/service/$http#deprecation-notice The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.
Sam Barnum

204

这里已经有一些不错的答案。但是值得一提的是,提供的并行性有所不同:

  • success() 返回原始承诺
  • then() 返回新的承诺

区别在于then()驱动顺序操作,因为每个调用都返回一个新的Promise。

$http.get(/*...*/).
  then(function seqFunc1(response){/*...*/}).
  then(function seqFunc2(response){/*...*/})
  1. $http.get()
  2. seqFunc1()
  3. seqFunc2()

success() 驱动程序并行运行,因为处理程序按相同的承诺进行链接。

$http(/*...*/).
  success(function parFunc1(data){/*...*/}).
  success(function parFunc2(data){/*...*/})
  1. $http.get()
  2. parFunc1()parFunc2()并行

3
请注意,一旦then达到,返回的新的Promise响应会导致successerror方法消失。同样,对于http错误响应(例如404),第一个then输入http.then(ok, err).then(ok, err)将传递给err处理程序,但随后的将被传递到ok处理程序中。基本上http.success().error().success().error()是可链接的,但是$ q Promise完全不同,因为它们都是关于Promise和专门处理顺序的(而不是http请求处理)。在仔细观察之前,我很难理解这一点。
jimmont 2014年

1
@jimmont successerror不是Promise的普通API,它们用螺栓连接到$ http()的返回值上。
event_jr 2014年

谢谢@event_jr,这对我来说很清楚,并在文档中进行了标注。(对我来说)不清楚的是$ q和$ http如何解决不同的问题以及返回新的诺言与传递相同的诺言-如您(超级有用)答案中所指出的。
2014年

1
由于JS是单线程的,因此并行表示什么?您是说执行顺序不确定吗?
Derek

2
@Derek第二个success将在第一个执行后但在其返回的任何诺言尚未解决之前执行,而第二个then将等待。如果您不返回承诺,则两者的行为相同。
塔林2015年

114

一些简单的GET请求的代码示例。也许这有助于理解差异。使用then

$http.get('/someURL').then(function(response) {
    var data = response.data,
        status = response.status,
        header = response.header,
        config = response.config;
    // success handler
}, function(response) {
    var data = response.data,
        status = response.status,
        header = response.header,
        config = response.config;
    // error handler
});

使用success/ error

$http.get('/someURL').success(function(data, status, header, config) {
    // success handler
}).error(function(data, status, header, config) {
    // error handler
});

5
谢谢,但是问题更多的是关于这些功能的不同之处,或者如果它们做同样的事情,它们为什么同时存在的原因。从文档中可以理解它们的用法不同。
ejoubaud

39
我个人喜欢短代码示例,那就是我在这里发布的示例。Angular文档有时会漏掉一些简短的精确示例。
TheHippo

2
重要的是要强调一个事实,第一个要点的响应对象包含第二个要点的“数据,状态,标题和配置”。这意味着响应对象具有一个深度层次。
geoom

将响应值传递给变量data,status,header,config比简单返回有什么好处response吗?
ᴍᴀᴛᴛʙᴀᴋᴇʀ

27

.then()是可链接的,将等待先前的.then()解析。

.success()和.error()可以链接在一起,但是它们都将立即触发(因此没有太多意义)

.success()和.error()对于简单的调用(简单的创建者)非常有用:

$http.post('/getUser').success(function(user){ 
   ... 
})

因此您不必输入以下内容:

$http.post('getUser').then(function(response){
  var user = response.data;
})

但通常我使用.catch()处理所有错误:

$http.get(...)
    .then(function(response){ 
      // successHandler
      // do some stuff
      return $http.get('/somethingelse') // get more data
    })
    .then(anotherSuccessHandler)
    .catch(errorHandler)

如果需要支持<= IE8,则可以这样编写.catch()和.finally()(在IE中保留方法):

    .then(successHandler)
    ['catch'](errorHandler)

工作示例:

这是我以更具编码性的格式编写的内容,以刷新我的记忆,了解如何处理错误等:

http://jsfiddle.net/nalberg/v95tekz2/


唯一显示“回馈承诺”工作原理的
答案

17

仅出于完成目的,这是一个指示差异的代码示例:

成功\错误:

$http.get('/someURL')
.success(function(data, status, header, config) {
    // success handler
})
.error(function(data, status, header, config) {
    // error handler
});

然后:

$http.get('/someURL')
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
}).

太好了!您是否有一个示例可以说明串联的用处?
geoom

4
这个想法是“ then”方法更有用,因为您可以更轻松地一个接一个地编写异步操作。
MichaelLo 2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.