【问题标题】:synchronous http call in angularJSangularJS中的同步http调用
【发布时间】:2015-07-20 05:38:59
【问题描述】:

我有以下情况,我需要来自特定 url 的数据。我写了一个带有参数'url'的函数。在函数内部,我有一个调用 url 的 $http.get 方法。数据将返回给调用函数

var getData = function (url) {
    var data = "";

    $http.get(url)
        .success( function(response, status, headers, config) {
             data = response;
        })
        .error(function(errResp) {
             console.log("error fetching url");
        });
    return data;
}

问题如下,$http.get是异步的,在获取响应之前,函数返回。因此,调用函数将数据作为空字符串获取。如何强制函数在从 url 获取数据之前不返回?

【问题讨论】:

  • 您可以返回成功和错误函数本身,可以进一步使用......

标签: angularjs http http-get


【解决方案1】:

看看 promises 来克服这些问题,因为它们在 Angular 世界中无处不在。

你需要使用$q

var getData = function (url) {
    var data = "";
    var deferred = $q.defer();

    $http.get(url)
        .success( function(response, status, headers, config) {
             deferred.resolve(response);
        })
        .error(function(errResp) {
             deferred.reject({ message: "Really bad" });
        });
    return deferred.promise;
}

这是一篇关于promises and $q的好文章

更新:

仅供参考,$http 服务本身会返回一个承诺,因此在这种情况下不一定需要 $q(因此需要 anti-pattern)。

但不要让这成为跳过阅读有关 $q 和 promises 的原因。

所以上面的代码等价于:

var getData = function (url) {
    var data = "";
    return $http.get(url);
}

【讨论】:

  • 如何获取 promise 的值?
  • 是的,我知道。但我试图让 OP 的事情变得简单。如果一个人不知道第一手的承诺是什么,那么像“$http 本身返回一个承诺”这样的声明可能会让任何人感到困惑。
  • 为什么这个答案被标记为正确?此解决方案不会使 http 请求同步,它仍然是异步的。
  • @CarlosCalla:我有没有在我的解决方案的任何地方提到这是一种“同步”技术?您可能只是阅读了问题标题,但没有看到 OP 的实际要求。如果你错过了,这里是他的问题的要点。 OP 实际上是从函数返回一些东西,其值确实被推断为“异步”。请参阅 如何强制函数在从 url 获取数据之前不返回 部分。解决此问题的方法不是使代码同步。因此,我在回答中提到了“承诺”。
【解决方案2】:

你也可以使用 $q.all() 方法来解决这个问题

var requestPromise = [];

var getData = function (url) {
    var data = "";

    var httpPromise = $http.get(url)
        .success( function(response, status, headers, config) {
             data = response;
        })
        .error(function(errResp) {
             console.log("error fetching url");
        });

    requestPromise.push(httpPromise);
}

在调用函数中

$q.all(requestPromise).then(function(data) {

    //this is entered only after http.get is successful
});

确保将 $q 作为依赖注入。希望对你有帮助

【讨论】:

    【解决方案3】:

    你的功能似乎是多余的。只需使用$http.get(url),因为在您使用它之前您并没有真正做任何其他事情。

    var url = 'foo/bar';
    
    $http
        .get(url)
        .success( function(response, status, headers, config) {
            $scope.data = response;
        })
        .error(function(errResp) {
            console.log("error fetching url");
        });
    

    或者,如果您稍后需要访问承诺,只需将其分配给变量;

    var promise = $http.get(url);
    
    // some other code..
    
    promise.then(function(data){
       //.. do something with data
    });
    

    【讨论】:

      【解决方案4】:

      做你想做的事的典型方法是这样的:

      var getData = function(url, callback) {
          $http.get(url).success(function(response) {
              callback && callback(response);
          });
      };
      

      像这样使用:

      getData('/endpoint', function(data) {
          console.log(data);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-03
        • 2012-05-08
        • 2015-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-01
        相关资源
        最近更新 更多