【问题标题】:AngularJS: Why is .then() not waiting for the promise object to arriveAngularJS:为什么 .then() 不等待承诺对象到达
【发布时间】:2015-12-19 12:24:30
【问题描述】:

为了进行 API 调用,我创建了以下 Angular 服务。

(function (module) {
    module.service('APIService',function ($http, $q) {
        console.log("Reached APIService")
        var deferred = $q.defer();
        this.getData = function (requestURL) {
            console.log("Reached APIService @GET", requestURL);
            $http.get(requestURL).success(
                function (data, status) {
                    deferred.resolve(data);
                    console.log("In service",status,data);
                }).error(
                function (data, status) {
                    deferred.reject(data);
                    console.log(status);
                });
            return deferred.promise;
        };

        this.postData = function (requestURL, requestObj) {
            console.log("Reached APIService @POST", requestURL, requestObj);
            $http.post(requestURL, requestObj).success(
                function (data, status) {
                    deferred.resolve(data);
                    console.log(status);
                }).error(
                function (data, status) {
                    deferred.reject(data);
                    console.log(status);
                });
            return deferred.promise;
        };
    });
}(angular.module("MainApp")));

我已将它注入我的两个控制器中。但是,我面临以下问题:

  1. 当我第一次在第一个控制器中调用它时,它可以正常工作并返回所需的结果。但是,当我在第二个控制器中按如下方式调用它时:

        APIService.getData(Config + headerURL).then(function (response) {
            console.log(Config + headerURL);
            console.log("header response from API", response);
    
        },function(error) {
            console.log("API call for header data failed");
        });
    

由于我的服务返回一个承诺对象,我不希望 .then() 中的代码在服务数据到达之前工作。 但是,它在服务数据到达之前运行(不知道如何)。最奇怪的是,我在 .then() 中得到的响应实际上并不是来自这个 URL(Config+headerURL)的响应,而是从之前在第一个控制器中调用的不同 URL 获得的响应。 APIService 服务。

只是为了通知:来自当前 URL 的实际响应确实会在稍后阶段到达。

我知道异步调用,我认为在这种情况下它有一些事情要做,但我猜 .then() 在 Angular 中处理它。所以我很困惑这里有什么问题。有没有人能解释一下?

【问题讨论】:

    标签: javascript angularjs angular-services


    【解决方案1】:

    $http 已经返回一个承诺时,您通过创建自己的承诺来使用反模式

    在此服务中完全摆脱 $q 并简单地返回 $http

    this.getData = function (requestURL) {
        console.log("Reached APIService @GET", requestURL);
        return $http.get(requestURL).then(function (response) {
            return response.data;
            console.log("In service", status, data);
        }, function () {
            // errror handling here
        });
    
    };
    

    【讨论】:

      【解决方案2】:

      由于服务是单例的,因此您只有一个延迟对象的实例。

      一旦解决,就会一直被解决,所以下次调用getData,它会立即返回。

      你可以移动:

      var deferred = $q.defer();
      

      在您的 getData 和 postData 函数中。

      或者你可以只返回 $http 创建的承诺。

      【讨论】:

      • 好点..感谢提醒单身人士的概念。我绝对应该在我的方法中推迟。但是如果承诺立即解决并返回,我仍然没有得到,为什么以及如何在一段时间后从当前 URL 获得有效响应
      • @SaurabhTiwari,正如 bregnvig 所说,您只有一个延迟对象的实例。这意味着您第一次调用getData() 时,一切都会按预期工作,但第二次调用它时,您会得到相同的承诺并且该承诺已经解决。当您在已解决的承诺上调用 .then() 时,它会立即触发。
      • @Duncan:我很清楚你的意思。但正如我所提到的,我在一段时间后得到了新的回应。这就是现在困扰我的问题。这肯定意味着 getData 方法即使在发送了先前解决的 promise 之后也会执行
      • @SaurabhTiwari,是的,当第二个数据对象到达时,您会再次解决承诺,因此.then() 将再次触发。这可能不是定义的行为,因为您不应该多次解决承诺,但它非常有意义。为每个 getData() 调用创建对 $q.defer() 的新调用将解决问题。
      • 谢谢你们俩..希望事情能奏效。选择答案作为提醒单身人士接受的答案!!!
      【解决方案3】:

      试试这个,你需要return到http结果。

      this.getData = function (requestURL) {
                  console.log("Reached APIService @GET", requestURL);
                 return $http.get(requestURL) };
      

      【讨论】:

        【解决方案4】:

        看来您必须在 $http 调用中明确禁用缓存。

        $http.get({
          url: requestURL,
          cache: false
        })
        

        【讨论】:

        • 您的观点似乎是有效的,但正如我所说,预期的结果确实到达了。事实上,如果我看到,在 APIService 中编写的控制台,它会打印当前的 URL。所以当前的 URL 正在 APIService 内部进行处理。我的主要问题是 .then() 中的代码如何在不等待服务的情况下执行。
        猜你喜欢
        • 2021-10-14
        • 2019-04-29
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 2022-01-09
        • 2020-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多