在返回承诺的函数上使用 .success 时,未定义不是函数

Posted

技术标签:

【中文标题】在返回承诺的函数上使用 .success 时,未定义不是函数【英文标题】:Undefined is not a function when using .success on a function that returns a promise 【发布时间】:2014-10-23 03:59:25 【问题描述】:

我正在尝试通过编写登录函数来继续我对 Promise 的理解。 Login 函数是 AuthService 的一部分,它向我的服务器发送一个 http 请求并返回一个 Promise(如果用户被验证,则 Promise 被解析,否则被拒绝)。

在我的控制器中调用该函数时,我尝试使用 .success 和 .error ,因为该函数返回一个承诺,但我收到错误“未定义不是函数”。

这是我得到未定义错误的函数。

$scope.login = function(email, password) 
  return AuthService.login(email, password).success(function(data) 
    return console.log("login function returned", data);
  ).error((function(data) 
    return console.log("There was an error " + data);
  ));
;

这是我的服务

.service('AuthService', function($window, $rootScope, $q, $http) 
  return 
    login: function(email, password) 
      var deferred;
      deferred = $q.defer();
      $http.post('/dashboard/login', 
        email: email,
        password: password
      ).error(function(error, status) 
        console.log("Incorrect logi");
        return deferred.reject(error);
      ).success(function(data, status) 
        $window.sessionStorage["userInfo"] = JSON.stringify(data);
        return deferred.resolve(data);
      );
      return deferred.promise;
    
  ;
);

最让我困惑的是,经过研究,promise 似乎没有成功或错误方法,但 $http 是具有该方法的 promise。此外,如果他们没有成功和错误,你怎么知道某事是否是错误?最后,如果没有成功或错误方法,.reject 和 .resolve 的意义何在?

【问题讨论】:

我认为你想要“.then()”...他们几乎制作了一个“.done()”,但被冷落了,所以我们只有 then 【参考方案1】:

最让我困惑的是,经过研究,promise 似乎没有成功或错误方法,但 $http 是具有该方法的 promise

是的,确实如此。 $http 返回对象是承诺,出于遗留原因具有这些 .success.error 方法。

如果他们没有成功和错误,你怎么知道某事是否是错误?

将处理程序附加到 Promise 的标准方法是使用 .then() method,它还充当链接方法并为处理程序的结果返回一个新的 Promise。

所以代码看起来像这样(也是avoiding the deferred antipattern):

.service('AuthService', function($window, $rootScope, $q, $http) 
  return 
    login: function(email, password) 
      return $http.post('/dashboard/login', 
        email: email,
        password: password
      ).then(function(data, status) 
        $window.sessionStorage["userInfo"] = JSON.stringify(data);
        return data;
      , function(error, status) 
        console.log("Incorrect login");
        throw error;
      );
    
  ;
);

$scope.login = function(email, password) 
  return AuthService.login(email, password).then(function(data) 
    return console.log("login function returned", data);
  , function(err) 
    return console.log("There was an error " + err);
  );
;

【讨论】:

那么拒绝和解决的重点是什么?还有你所说的“将处理程序附加到一个承诺”是什么意思?你有例子吗? "attaching handlers" 正是successs/error 所做的——所以你“知道某事是否是错误”。 拒绝和解决的点是关于结果的通知,状态现在已经解决。他们这样做触发这个,并导致回调的调用(通过then 安装)。通常,当一个 API 已经返回一个 promise(例如$http)时,您根本不必处理这些延迟 - 它们太低级了。你只需要链接和组合 Promise。 所以基本上拒绝和解决是无用的......我将不得不做一些关于投掷的阅读。等等函数怎么知道err是一个错误? 不,当你创建一个promise时你需要它们(从无到有,凭空而来,除了异步回调什么都没有)。 then 也在内部使用它们。也许从this thread开始阅读

以上是关于在返回承诺的函数上使用 .success 时,未定义不是函数的主要内容,如果未能解决你的问题,请参考以下文章

返回承诺的函数必须是异步的

在自定义承诺上使用异步等待

在自定义承诺上使用异步等待

如何使用 .success 和 .error 在 Angularjs 中扩展 $q 承诺

对从异步函数返回的承诺感到非常困惑

C++ 承诺/未来:从函数返回哪个?