【问题标题】:AngularJS Promises - Simulate http promisesAngularJS Promises - 模拟 http 承诺
【发布时间】:2014-01-20 05:15:05
【问题描述】:

当我知道请求将在服务器端失败时,我想知道如何模拟一个承诺 $http。这是我的代码:

if ( !ng.isString(email) ) {
    var promise = $q.defer().promise;
    $q.reject();

    return promise;
}

return $http( {
         method : "PUT",
         url : "//localhost/update" ,
         data : { data: email } 
})

// Success handler
.success(response){ return response})

// Error handler
.error(errorMsg){ return errorMsg});

【问题讨论】:

  • 做 promise.reject() 而不是 $q.reject();
  • 我收到以下错误:Object # has no method 'reject'
  • 在那之后检查 isString 是否与 $http 函数有关?请简化您的参考
  • var x = $q.defer(); x.reject();返回 x.promise;

标签: angularjs promise


【解决方案1】:

您可以使用 resolve 和 reject 来控制数据流:

假设您有这样的服务:

var app = angular.module("mymodule.services", []);

app.factory("HttpRequest", ['$q', '$http', function(q, http) {
  var deferredData = q.defer();

  http.get('http://your-server.local/data.json').success(function(data) {
    //success, resolve your promise here
    deferredData.resolve(data);
  }).error(function(err) {
    //error, use reject here
    deferredData.reject(err);
  });

  return {
    get: function() {
      return deferredData.promise;
    }
  };
}]);

然后可以这样使用服务:

var app = angular.module("mymodule.controllers", ['mymodule.services']);

app.controller("MyCtrl", ['HttpRequest', '$scope', function(res, scope) {
  //the "then"-method of promises takes two functions as arguments, a success and an erro callback
  res.get().then(function(data) {
    //first one is the success callback
    scope.data = data;
  },
  function(err) {
    scope.err = err; 
  }); 
}]);

您可以在第二个回调中处理错误。

【讨论】:

  • 感谢您的回答!听起来不错,但我需要能够使用 successerror 方法而不是 then
  • $q 在 Angular 中提供的承诺没有开箱即用的方法,我建议在这里修改它们:stackoverflow.com/questions/17686612/…
【解决方案2】:

好的,我可以弄清楚如何模拟 $http 对象返回的相同承诺。感谢大家的回答。我可以把它们都考虑进去。这是我的解决方案:

if ( !ng.isString(email) ) {

    // We need to create a promise like the one returned by the 
    // $http object (with the success and error methods)
    // to stay consistent.
    var promise = $q.reject("error with email");

    // Defining success and error method for callbacks. 
    // but it should never be called since the promise 
    // is already rejected.
    promise.success = function(fn){
       promise.then(function(response){
          fn(response)
       }, null);
          return promise
    };

    promise.error = function(fn){
       promise.then(null, function(response){
          fn(response)
       });
       return promise;
    };

    return promise;
}

return $http( {
         method : "PUT",
         url : "//localhost/update" ,
         data : { data: email } 
})

// Success handler
.success(response){ return response})

// Error handler
.error(errorMsg){ return errorMsg});

【讨论】:

  • 我想知道为什么 successerror 方法尚未在承诺中定义。看起来很有用,你们不觉得吗?
  • 我需要做这样的事情。我的解决方案类似,但我想我会指出 promise.then(function(response){ fn(response); }) 实际上与 promise.then(fn) 相同。
【解决方案3】:

$http 在 angularJS 中返回一个承诺。你可以这样做:

var promise = $http(...) ;
promise.then(function(data) {}, function(error){});

您可能会在 jQuery ajax 调用中寻找成功和错误函数,但在 angularJS 中起作用的是不同的东西。您可能需要遵循它才能使其正常工作。

您可以告诉我们更多关于您需要使用成功和错误的原因,以便我们找到一种方法使其适用于您的案例。

【讨论】:

    【解决方案4】:

    这样的事情应该可以工作:

    if ( !ng.isString(email) ) 
        return $q.reject("Email is invalid.");  // returns rejected promise
    
    return $http( {
             method : "PUT",
             url : "//localhost/update" ,
             data : { data: email } 
    });
    

    然后在您的代码中将其用作常规承诺

    mypromise.then(function(x) { do something with x.data }, function(error) { alert(error)});
    

    【讨论】:

    • 感谢您的回答!听起来也不错,但我需要能够使用 successerror 方法而不是 then...
    【解决方案5】:

    根据您的建议(并调试 Angularjs 代码),我发现了一种更简化的方法,可以拒绝或解决。

    if (alreadyLoaded){
        var defered = $q.defer();
        defered.success = function(fn){
            defered.promise.then(fn);
            return defered;
        };
        defered.error = function(fn){
            defered.promise.then(null, fn);//or defered.promise.catch(fn)
            return defered;
        };
        if(data.invalid)
            defered.reject("arbitrary error");
        else
            defered.resolve(data);
        return defered;
    }else {
        return $http.get(...);
    }
    

    successerror 方法都返回 this 以允许排队回调)

    【讨论】:

      【解决方案6】:

      你的语法有点乱。试试这个:

      var deferred = $q.defer();
      $q.reject();
      return deferred.promise;
      

      【讨论】:

      • 感谢您的回答!但是因为我需要能够使用successerror 方法而不是then,所以我收到以下错误:Object # has no method 'success'
      • 在 HttpPromise 和 Promise 之间对抗不同的 Promise 接口
      猜你喜欢
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2017-09-04
      • 2016-09-29
      • 2015-03-15
      • 1970-01-01
      相关资源
      最近更新 更多