web-dev-qa-db-ja.com

AJAX "get"関数を同期させる/結果を取得する方法は?

$ .get関数の問題が発生しています。 URLにはJSONが含まれています

私のコード:

 xyz = null

    $.get('http://www.someurl.com/123=json', function(data) {
       var xyz = data.positions[0].latitude;
    });

alert(xyz);
//some more code using xyz variable

$.get非同期であるため、xyzがnullの結果を警告することを知っています。

では、このget関数の外でxyzを使用する方法はありますか?

16
Diolor

本当の答えは[〜#〜] no [〜#〜]ですが、これを使用できます:

function useXYZ(){
    alert(xyz);
}

xyz = null        

$.get('http://www.someurl.com/123=json', function(data) {
   xyz = data.positions[0].latitude;
   useXYZ();
});

getはショートカットです。以下を使用して、同じことを同期的に行うことができます。

var xyz = null


$.ajax({ url: 'http://www.someurl.com/123=json', 
         async: false,
         dataType: 'json',
         success: function(data) {
              xyz = data.positions[0].latitude;
            }
        });


alert(xyz);

ただし、ajax呼び出しの前にxyz変数を宣言する必要があります。

23
moribvndvs

これはJavascriptの一般的な問題です。 Javascriptコードは、継続渡しスタイルで記述する必要があります。その迷惑ですが、あまり考えずに変換できるものです。

基本的に、私たちが何かを持っているときはいつでも

var x = someSyncFunction(a, b, c);
//do something with x
console.log(x);

関数が継続関数に戻った後にすべてのコードを作成し、xを変数から継続コールバックのパラメーターに変換することで、非同期コードに変換できます。

someAsyncFunction(a, b, c, function(x){
    //do something with x;
    console.log(x);
});

紛らわしいコードを書くのは非常に簡単であることに注意する必要があります。覚えておくべき良いトリックは、独自の関数にコールバックも受信させることができるということです。これにより、さまざまな関数で使用できるようになります(値を返す通常の同期ヘルパー関数をさまざまな関数で使用できるように)

var getXyz = function(onResult){ //async functions that return do so via callbacks
                                 //you can also another callback for errors (kind of analogous to throw)
    $.get('http://www.someurl.com/123=json', function(data) {
       var xyz = data.positions[0].latitude;
        onResult(xyz); //instead of writing "return xyz", we pass x to the callback explicitely.
    });
};

getXyz(function(xyz){ //this would look like "var xyz = getXyz();" if it were sync code instead.
    console.log('got xyz');
});

ここでの秘訣は、関数からのすべてのreturnステートメントをコールバック関数の呼び出しに変更することです。非同期関数が返されないかのように考えてください。誰かに値を返す唯一の方法は、その値をコールバックに渡すことです。


これらすべてを行う簡単な方法がないのはなぜかと疑問に思うかもしれません。そうですね、Javascriptの代わりに別の言語を使用しない限り(または少なくとも同期スタイルで非同期コードを記述できるが、通常のJavascriptに自動的にコンパイルされるもの)はありません。

4
hugomg