2011-07-27 25 views
326

この質問は何度も尋ねられます。しかし、まだ私はものを得ることができません。非同期コールバック関数から値を返す方法は?

私はコールバックからいくつかの価値を得たいと思っています。明確にするために、下のスクリプトを見てください。

function foo(address){ 

     // google map stuff 
     geocoder.geocode({ 'address': address}, function(results, status) { 
      results[0].geometry.location; // I want to return this value 
     }) 

    } 
    foo(); //result should be results[0].geometry.location; value 

「未定義」という値を返すようにしようとするとします。私はSOからのいくつかのアイデアに従ったが、 はまだ失敗する。

ものは以下のとおりです。

function foo(address){ 
    var returnvalue;  
    geocoder.geocode({ 'address': address}, function(results, status) { 
     returnvalue = results[0].geometry.location; 
    }) 
    return returnvalue; 
} 
foo(); //still undefined 
+11

ここにいる人[**この質問を最初にお読みください**](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call)この問題に効果的に取り組む方法について説明します。 –

+0

** [変数を関数内で修正した後に変数が変更されないのはなぜですか? - 非同期コードリファレンス](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron)**は、手元にある問題のより一般的で詳細な説明。 –

+0

angularJsに付属している$ q libraryのように、Qまたはその変形を使用してください。そして振り返ってはいけません。非同期関数は直ちにundefinedを返します。だから決してあなたの時間を無駄にすることを試みること無駄にしないでください。また、通常と同じように、非同期関数では 'return'キーワードを使用しないでください。代わりに、延期された約束を使用してください。 deferred.resolve(あなたがやりたいSTUFF)、後で単純にそれを返すことができます。 'return deferred.promise; ' :) – ISONecroMAn

答えて

336

同期メソッド内で非同期呼び出しから戻ることはできません。これは不可能です。あなたは戻り値

function foo(address, fn){ 
    geocoder.geocode({ 'address': address}, function(results, status) { 
    fn(results[0].geometry.location); 
    }); 
} 

foo("address", function(location){ 
    alert(location); // this is where you get the return value 
}); 

を受け取ることになりますfooへのコールバックを渡す必要があり、この場合には

事インナー関数呼び出しが非同期である場合、すべての機能「ラッピング」この呼び出しが必要ですまた、レスポンスを返すためには非同期である必要があります。

コールバックが多い場合は、飛び込みを考えてpromise library like Qを使用することを検討してください。

+3

:)それは強くはない、それはちょうど方法です。非同期メソッドを使用してデータを渡すと、関数チェーン全体が非同期になります。 –

+0

非同期関数の連鎖がオブジェクトを操作する場合、 'graph'オブジェクトを考えてみましょう。とにかく、そのオブジェクトへの参照を取得してupdate()のようなものを呼び出すことはできますか? – user2483724

+2

最終的にこれを意味するためにUpvote。 –

18

それはコールバックから値を返すためにも意味がありません。代わりに、あなたのコールバックの中でしたい "foo()"仕事をしてください。

非同期コールバックは、イベントが発生したときにブラウザまたはGoogleジオコーディングライブラリのようなフレームワークによって呼び出されます。返される値の場所はありません。コールバック関数の値を返しますが、関数を呼び出すコードでは戻り値には注意しません。

14

あなたはjQueryのを使用することが起こる場合は、あなたがこれに打撃与えたいと思うかもしれません: http://api.jquery.com/category/deferred-object/

それは、AJAXリクエスト(または任意の非同期操作)が完了するまで、あなたのコールバック関数の実行を延期することを可能にします。これは、いくつかのAjaxリクエストがすべて完了したらコールバックを呼び出すためにも使用できます。

関連する問題