angularJS 中的同步 http 调用

synchronous http call in angularJS

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

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是异步的,在获取响应之前,函数returns。因此调用函数将数据作为空字符串获取。在从 url 获取数据之前,如何强制函数不 return?

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

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

像这样使用:

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

看看 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服务本身returns一个承诺,所以在这种情况下不一定需要$q(因此anti-pattern).

但不要因此而跳过阅读 $q 和 promises 的内容。

所以上面的代码等同于:

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

你的功能似乎是多余的。只需使用 $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
});

你也可以用$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 作为依赖注入。希望对你有帮助