7

当我知道请求将在服务器端失败时,我想知道如何模拟一个承诺 $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});
4

6 回答 6

5

您可以使用 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; 
  }); 
}]);

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

于 2013-08-14T22:33:45.990 回答
5

好的,我可以弄清楚如何模拟 $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});
于 2013-08-15T14:24:19.983 回答
3

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

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

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

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

于 2013-08-15T13:58:52.510 回答
1

像这样的东西应该工作:

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)});
于 2013-08-14T23:37:39.633 回答
1

在下面使用您的建议(并调试 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以允许排队回调)

于 2014-01-19T21:15:05.320 回答
0

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

var deferred = $q.defer();
$q.reject();
return deferred.promise;
于 2013-08-14T22:29:27.527 回答