【问题标题】:AngularJS then() behaves differently than success()-error() [duplicate]AngularJS then() 的行为不同于 success()-error() [重复]
【发布时间】:2016-05-26 17:37:49
【问题描述】:

由于 success() 和 error() 函数在 AngularJS 中已被弃用,我正在更新我的代码,将它们替换为 then()。现在根据我的理解,这两段代码的行为应该是相同的:

$http
   .get(/* some params */)
   .success(function() {
      // success cases here
   })
   .error(function() {
      // error cases here
   });

还有

$http
   .get(/* some params */)
   .then(function() {
      // success cases here
   }, function() {
      // error cases here
   });

但在某些情况下,我的行为会有所不同。您能否向我解释为什么会发生这种情况,更重要的是,使用then() 函数保证相同行为的方法是什么?

【问题讨论】:

    标签: angularjs angular-promise


    【解决方案1】:

    .success 和 .error 方法忽略返回值。
    因此,它们不适合链接。

    var httpPromise = $http
           .get(/* some params */)
           .success(function onSuccess(data, status, headers, config) {
              var modifiedData = doModify(data);
              //return value ignored
              return modifiedData;
           })
           .error(function onError(data, status, headers, config) {
              // error cases here
           });
    
    httpPromise.then(function onFullfilled(response) {
        //chained data lost
        //instead there is a response object
        console.log(response.data); //original data
        console.log(response.status); //original status
    });
    

    另一方面,.then 和.catch 方法返回一个派生的promise 适合链接返回(或抛出)的值或一个新的promise。

    var derivedPromise = $http
           .get(/* some params */)
           .then(function onFulfilled(response) {
              console.log(response.data); //original data
              console.log(response.status); //original status
    
              var modifiedData = doModify(response.data);
              //return a value for chaining
              return modifiedData;
           })
           .catch(function onRejected(response) {
              // error cases here
           });
    
    derivedPromise.then(function onFullfilled(modifiedData) {
        //data from chaining
        console.log(modifiedData);
    });
    

    响应对象与四个参数

    还要注意$http 服务在调用提供给.success 和.error 方法的函数时提供四个参数 (data, status, headers, config)。

    $q 服务只为提供给.then 或.catch 方法的函数提供一个参数(响应)。对于由$http 服务创建的承诺,响应对象具有以下属性:1

    • data – {string|Object} – 使用转换函数转换的响应正文。
    • status – {number} – 响应的 HTTP 状态代码。
    • headers – {function([headerName])} – Header getter 函数。
    • config – {Object} – 用于生成请求的配置对象。
    • statusText – {string} – 响应的 HTTP 状态文本。

    链式承诺

    因为调用 Promise 的 then 方法会返回一个新的派生 Promise,所以很容易创建一个 Promise 链。可以创建任意长度的链,并且由于可以使用另一个 Promise 来解决一个 Promise(这将进一步推迟其解决方案),因此可以在链中的任何点暂停/推迟对 Promise 的解决。这使得实现强大的 API 成为可能。2


    更新

    .success 和 .error 方法已被弃用并从 AngularJS V1.6 中删除。

    有关详细信息,请参阅

    【讨论】:

      【解决方案2】:

      一个重要的区别是您可能应该使用.then().catch() 而不是.then(function(), function())。 [1] 据我所知,双参数 then (其中第二个函数是错误处理程序)不会捕获第一个函数中的错误。 IOW:如果 a() 抛出错误,$http.get().then(a, b) 将不会调用 b(),而 $http.get().then(a).catch(b) 会。

      你还有哪些不同的行为?

      1:标准化的 Promise API - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

      【讨论】:

        【解决方案3】:

        success 函数和 promise 回调确实接收到不同的对象。如docs 中所述,promise 回调接收包含状态、标头、数据等的响应对象。成功函数仅返回该对象的数据字段(响应主体)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-01
          • 1970-01-01
          • 2016-08-03
          • 2013-04-29
          • 2014-06-26
          • 2013-08-04
          • 2018-07-22
          • 2018-11-27
          相关资源
          最近更新 更多