11

私が過去に苦労し、今日も苦労しているのは、応答を受け取るまで API/AJAX が続行できないことです。現在、私は Facebook API を使用しています。呼び出しから応答を取得して返す必要がありますが、API 呼び出しから応答を取得する前に関数が返されます。原因はわかっているのに、それを防ぐ方法がわかりません!これが私のコードです...

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;

}

// - - - 編集

このような提案をする人がいることに気付きました...

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

3 に答える 3

21

1 日に 100 回も聞かれ、答えが 1 つではないように思える質問。

呼び出しは非同期であるため、1 つのステップで行うことはできません。あなたが期待するものの基本的な例。

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

実際に起こっていること:

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

あなたがする必要があるのは、それを2つの部分に分割することです.

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);
于 2012-06-12T17:17:40.313 に答える
7

JavaScript には、待機または譲歩の概念はありません。JavaScript は、中断することなくコードの最後まで実行を続けます。最初は奇妙で面倒に思えますが、利点があります。

したがって、このようなシナリオのアイデアは、応答を受け取った後に実行したいコードを、FB.api() に渡すコールバックに入れる必要があるということです。応答を受信したときに実行できるように、return ステートメントの後のコードを応答コールバックに分割する必要があります。

これは、JavaScript がほとんどの言語 (C++/Java など) のようなものである場合に期待されるものです。

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

ただし、JavaScript の考え方は、非同期を処理するときのコールバックに基づいています。

SomeAsyncCall(function(result) {
    var data = result.GetData();
    //now do stuff with data
});
于 2012-06-12T17:07:12.627 に答える
4

そのようなことをすると、リクエストの期間中、ユーザーのブラウザがブロックされるため、返送を阻止したくありません。何らかの理由(輻輳、サイトのメンテナンスなど)でリクエストがハングした場合、ブラウザはユーザー入力に応答しなくなり、ユーザーを混乱させます。

次の代わりに:

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();
于 2012-06-12T17:13:31.423 に答える