2012-06-12 16 views
6

私は過去に苦労していましたが、今日は苦労してAPI/AJAXが応答を受け取るまで続けることができません。現在私はFacebook APIを使って作業しています。私は呼び出しからの応答を取得し、それを返す必要がありますが、何が起こっているかは、API呼び出しからの応答を得る前に関数が返ってくるということです。私はなぜそれが起こっているのか知っている、私はちょうどそれを防止する方法を見つけることができません!ここに私のコードは...だAPIコールがJavascriptで終了するまで待ってから

function makeCall(){ 

var finalresponse = ""; 
    var body = 'Test post'; 

     FB.api('/me/feed', 'post', { message: body }, function(response) { 
     if (!response || response.error) { 
     finalresponse = response.error; 
     } else { 
      finalresponse = 'Post ID: ' + response.id; 
     } 
     }); 
     return finalresponse; 

} 

// -----私は何人かの人々がこのような何かを示唆した気づい

EDIT ...

function makeCall(){ 
var finalresponse = ""; 
FB.api('/me/feed', 'post', { message: body }, function(response) { 
     if (!response || response.error) { 
     finalresponse = response.error; 
     return finalresponse; 
     } else { 
      finalresponse = 'Post ID: ' + response.id; 
      return finalresponse; 
     } 
     }); 
} 

しかし、これは未定義

を返します。

//更新を基に編集

function share_share(action_id){ 

    var finalresponse = makeCall(action_id, process); 
    return finalresponse; 

} 

function makeCall(action_id, callback){ 

var body = 'Test post'; 
     FB.api('/me/feed', 'post', { message: body }, function (response) { 
     if (!response || response.error) { 
     var finalresponse = response.error; 
     } else { 
      finalresponse = 'Post ID: ' + response.id; 
     } 
     callback(action_id, finalresponse); 
     }); 

} 
function process(action_id, finalresponse){ 
    console.log(finalresponse); 
} 
+0

あなたの 'return finalresponse;はAPIコールの外にあるためだと思います。 –

+0

FB.apiが完了する前に戻ります – Dhiraj

+0

編集で提供したコードが正しくありません。コールバックのfinalResponseを返すのは、応答コールバックの呼び出し元に返されます。 make呼び出しが何も返さないので、未定義の理由はmakeCall()の呼び出し側に返されます。 –

答えて

13

100回の日を求め、1つの答えを持っていることは不可能と思われるている質問を。

呼び出しは非同期であるため、一度に実行することはできません。あなたが期待するものの基本的な例。

function one() { 
    var a; 
    window.setTimeout( 
    function() { 
     a = 1; 
    }, 2000); 
    return a; //This line does not wait for the asynchronous call [setTimeout/ajax call] to run. It just goes! 
} 
alert(one()); 

は何をする必要がある二つの部分に分割してある:実際に何が起こっている

function one() { 
    var a = 1; 
    return a; 
} 
alert(one()); 

function one(callback) { 
    window.setTimeout(function(){ //acting like this is an Ajax call 
     var a = 1; 
     callback(a); 
    },2000); 
} 
function two(response) { 
    alert(response); 
} 
one(two); 

あなたの場合、2つのまとまりで処理するためにコードを分割する必要があります。

function makeCall(callback) { 
    var body = 'Test post'; 
     FB.api('/me/feed', 'post', { message: body }, function (response) { 
     if (!response || response.error) { 
     var finalresponse = response.error; 
     } else { 
      finalresponse = 'Post ID: ' + response.id; 
     } 
     callback(finalresponse); 
     }); 
} 


function processResponse(response) { 
    console.log(response); 
} 
makeCall(processResponse); 
+1

そして、@Pointyは私の編集を殺しました。もう一度やり直す時間です。 – epascarello

+0

ありがとう、これは本当に私を理解するのに役立ちましたが、私は元の呼び出しに応答を返す場合はどうすればいいですか?上記の最後の編集を参照してください。私は価値を得てそれを返すのです。だから基本的に私はshare_shareを呼び出す関数を持っていて、返される必要があります。 –

+0

返されるだけではなく、コールバックでなければなりません。 'return finalresponse;は前と同じですが、ちょっと違う方法です! – epascarello

6

JavaScriptでは、待機または降伏の概念はありません。 JavaScriptは、途切れることなく、コードの最後まで実行し続けます。それは最初は奇妙で厄介なようですが、それには利点があります。

このようなシナリオでは、応答を受け取った後に実行するコードをFB.api()に渡すコールバックに入れるべきです。 return文の後のコードを応答コールバックに分解して、応答が受信されたときに実行できるようにする必要があります。

これは、それが(例えばC++/Javaなど)、ほとんどの言語のようだった場合は、JavaScriptからを期待するかもしれないです:JavaScriptで

var futureResult = SomeAsyncCall(); 
futureResult.Wait(); //wait untill SomeAsyncCall has returned 
var data = futureResult.GetData(); 
//now do stuff with data 

アイデア非同期性に対処するとき、しかし、コールバックの周りに基づいています:

SomeAsyncCall(function(result) { 
    var data = result.GetData(); 
    //now do stuff with data 
}); 
+0

お世話になりましたが、これを達成するためのご提案はありますか? –

+0

アイデアを明確にするために例を追加しました。 –

0

あなたは、要求の期間中、ユーザーのブラウザをブロックするようなことをやって、それを返すことから防ぐためにしたくありません。要求が何らかの理由(輻輳、サイト保守など)でハングした場合、ブラウザはユーザーの入力に応答せず、結果としてユーザーが不調になってしまいます。代わりに、次のことを行うための

var res = makeCall(); 
if(res) 
{ 
    // do stuff 
} 

はこれを行います。

function makeCall(){ 
    FB.api('/me/feed', 'post', { message: body }, function(response) { 
     if (response && !response.error) { 
      // do stuff 
     } 
    }); 
} 

makeCall(); 
関連する問題