【问题标题】:AngularJS - Cannot get $q.reject and to workAngularJS - 无法获得 $q.reject 和工作
【发布时间】:2016-01-02 10:59:59
【问题描述】:

看看我的代码示例:

我已将其简化为(我认为是)最基本的内容,并且我正在设置错误deferred.reject is not a function

angular
    .module('myApp')
    .service('myService', MyService);

MyService.$inject = ['$http', '$q'];

function MyService($http, $q) {
    var self = this;

    self.getResult = getResult;

    function getResult(id) {
        var deferred = $q.defer();

        deferred = $http.get('my/api/method', { params: { id: id } })
            .then(getResultCompleted)
            .catch(getResultFailed);

        function getResultCompleted(response) {
            if (response.data.ID > 0) {
                deferred.resolve(response.data);
            } else {
                deferred.reject(response);
            }
        }

        function getResultFailed(response) {
            deferred.reject(response);
        }

        return deferred.promise;
    }
}

注意:我知道我可以通过简单地返回 $http 调用的结果来让它工作,但是为了理解这些承诺对象,我想看看我是否能得到这个通过声明和返回deferred 来工作,如上所示

谢谢!

【问题讨论】:

  • $http.get() 返回承诺,但不延迟
  • @Vadim:我不明白。你能详细说明一下吗?
  • 我指的是deferred = $http.get() 字符串。这是不正确的,因为$http.get() 返回的不是延迟对象,而是承诺。所以,你可以直接返回$http.get

标签: javascript ajax angularjs promise angular-promise


【解决方案1】:

您正在创建自定义 Promise 并从您的方法中返回它,但意味着在处理它时您正在用 $http.get 覆盖 deferred(custom Promise object),它还返回具有 .then.catch 的 Promise方法(没有resolve & reject 方法)。由于该分配,您无法从 deferred 对象访问 .resolve.reject

deferred = $http.get('my/api/method', { params: { id: id } })

应该只是

$http.get('my/api/method', { params: { id: id } })

【讨论】:

  • 谢谢@PankajParkar。我这里还是有点不清楚。如果它被赋值为 $http.get 的返回结果的值,这本质上是不是意味着它接受了这个值?
  • @Ricky 不。。这不是承诺的工作方式。承诺意味着你说过,我有一些东西要回报,过一段时间我会得到它。这就是你创建var deferred = $q.defer(); 和当您收到回复时,您将其设为 resolve 与数据和 reject 与相同的数据..如果您在其之间执行deferred = $http.get('my/api/method', { params: { id: id } }) ..它将清除整个对象传统的$http.get promise 对象将引入它..
【解决方案2】:

由于$http.get() 返回promise 并且成功回调支持链接API,您可以在回调中定义新的延迟对象并从那里返回:

angular
    .module('myApp')
    .service('myService', MyService);

MyService.$inject = ['$http', '$q'];

function MyService($http, $q) {
    var self = this;

    self.getResult = getResult;

    function getResultCompleted(response) { // Tip: Define callback outside of getResult in order to avoid creating new instance of it each time getResult is called
        var deferred = $q.defer();
        if (response.data.ID > 0) {
            deferred.resolve(response.data);
        } else {
            deferred.reject(response);
        }
        return deferred.promise;
    }

    function getResult(id) {
        return $http.get('my/api/method', { params: { id: id } })
            .then(getResultCompleted);
    }
}

注意,不再有错误回调(只是因为在这种情况下它是多余的)。

如果请求失败,将返回来自$http.get() 的原始拒绝promise,否则将使用来自成功回调的全新promise 用于后续.then() 调用。

【讨论】:

  • 谢谢@Vadim。 deferred 会在哪里下注?我在您的代码中没有看到它(尽管我可能错过了)
  • @Vadim 我不明白你为什么在玩deferred 对象,因为你已经返回了$http.get 承诺
  • @PankajParkar 一旦承诺得到解决,你就不能再拒绝它了。由于来自$http 的原始承诺已经解决,您需要在特定条件下拒绝它,您需要创建新的承诺,为此您需要新的延迟。
  • @Vadim 你确定吗?它不像你想的那样,因为你返回的承诺就像return $http.get('my/api/method', { params: { id: id } }) 行,它应该是return deferred.promise 让它工作
  • @PankajParkar 看看这个 plunk:plnkr.co/edit/ALbjvYlskBqMAgHH6bu3?p=preview。要了解它是如何工作的,您可以使用$http.get() 的 URL
猜你喜欢
  • 2015-09-30
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 2023-03-12
相关资源
最近更新 更多