web-dev-qa-db-ja.com

非同期コールバック関数から値を返す方法

この質問はSOで何度も聞かれます。それでも私は物事を手に入れることができません。

コールバックから何らかの価値を得たいのです。明確にするために以下のスクリプトを見てください。

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

その値を返そうとすると、単に "undefined"になります。私はSOからいくつかのアイデアに従ったが、それでも失敗する。

それらは:

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

同期メソッド内で非同期呼び出しから戻ることはできないため、これは不可能です。

この場合、戻り値を受け取るfooにコールバックを渡す必要があります。

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
});

重要なのは、内部の関数呼び出しが非同期の場合、この呼び出しを「ラップ」するすべての関数も、応答を「返す」ためには非同期でなければならないということです。

あなたがたくさんのコールバックを持っているなら、あなたは思い切って取ることを考えるかもしれませんそして Qのような約束のライブラリ を使います。

415
Sean Kinsey

コールバックから値を返すことは意味がありません。その代わりに、あなたがやりたい "foo()"作業を inside あなたのコールバックに対して実行してください。

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

20
Pointy

たまたまjQueryを使用している場合は、これを試してみるとよいでしょう。 http://api.jquery.com/category/deferred-object/

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

15
Alex Heyd