web-dev-qa-db-ja.com

angularJSの同期http呼び出し

次のシナリオがあり、特定の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からデータが取得されるまで関数を返さないようにするにはどうすればよいですか?

28
clearScreen

これらの問題はangularの世界で使われているため、promisesを見て問題を克服してください。

$ 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と$ q に関する素敵な記事があります

UPDATE:

参考までに、$httpサービス自体はpromiseを返しますなので、このシナリオでは$qは必ずしも必要ではありません(したがって アンチパターン )。

ただし、これが$ qとpromiseの読み取りをスキップする理由にならないようにしてください。

したがって、上記のコードは次のコードと同等です。

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

この問題を解決するには、$ 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を必ず注入してください。それが役に立てば幸い

9
akashrajkn

あなたの機能は冗長なようです。とにかくそれを使用する前に他に何もしていないので、$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
});
5
Matt Herbstritt

あなたがしたいことをする典型的な方法は次のようなものです:

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

次のように使用します:

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