これは 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 に自動的にコンパイルされるもの) を使用しない限り、そうではありません。