在继续之前,在Javascript中等待API调用完成

时间:2022-06-08 20:53:49

something I've struggled with in the past and am struggling with today is preventing an API/AJAX from continuing until you've recieved your response. currently I'm working with the Facebook API. I need to get a response from a call then return it but what's happening is that my function is returning before I ever get a response from the API call. I know why it's happening, I just can't figure out how to prevent it! Here's my code...

过去我一直在纠结的事情,现在正在努力阻止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;

}

// ----- EDIT

/ / - - - - - -编辑

I noticed some people suggested something like this...

我注意到有些人提出这样的建议……

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

But this returns undefined

但这回报未定义

// EDIT BASED ON UPDATES

//根据更新进行编辑

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

3 个解决方案

#1


13  

The question that is asked 100 times a day and seems impossible to have one answer.

这个问题每天被问100次,似乎不可能有一个答案。

The call is asynchronous so it is impossible to do it in one step. Basic example of what you expect.

调用是异步的,所以不可能一步完成。你所期望的基本例子。

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

What is actually happening:

到底发生了什么:

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

What you need to do is break it up into two parts.

你需要做的是把它分成两部分。

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

So in your case you would need to break up your code to handle it in two chunks.

所以在你的例子中,你需要把你的代码分成两部分来处理。

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

#2


6  

In JavaScript, there is no concept of waiting or yielding. JavaScript continues execution, without interruption, of your code to its end. It seems weird and troublesome at first, but it has its advantages.

在JavaScript中,没有等待或屈服的概念。JavaScript将继续执行代码,而不会中断。一开始它看起来很奇怪,很麻烦,但是它有它的优点。

So the idea in scenarios such as this is that the code you wish to execute after receiving your response should be put into the callback that you give to FB.api(). You'll have to break out the code after your return statement into the response callback so that it can be executed when the response is received.

因此,在这样的场景中,您希望在接收到响应后执行的代码应该放在给FB.api()的回调中。您必须在返回语句之后将代码分解到响应回调中,以便在接收响应时执行它。

This is what you might expect from JavaScript if it were like most languages (such as C++/Java):

如果JavaScript像大多数语言(如c++ /Java)一样,您可能会期望它是这样的:

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

The idea in JavaScript, however, is based around callbacks when dealing with asynchrony:

然而,JavaScript的想法是基于在处理异步时的回调:

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

#3


0  

You don't want to prevent from returning it as doing such a thing will block the user's browser for the duration of the request. If the request hangs for whatever reason (congestion, site maintenance, etc...) the browser will become unresponsive to any user input resulting in upset users.

您不希望阻止它返回,因为这样做会在请求期间阻塞用户的浏览器。如果请求因任何原因(拥塞、站点维护等)而挂起,浏览器将对任何用户输入失去响应,从而导致用户不满。

Instead of doing the following:

而不是做以下的事:

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

Do this:

这样做:

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

makeCall();

#1


13  

The question that is asked 100 times a day and seems impossible to have one answer.

这个问题每天被问100次,似乎不可能有一个答案。

The call is asynchronous so it is impossible to do it in one step. Basic example of what you expect.

调用是异步的,所以不可能一步完成。你所期望的基本例子。

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

What is actually happening:

到底发生了什么:

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

What you need to do is break it up into two parts.

你需要做的是把它分成两部分。

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

So in your case you would need to break up your code to handle it in two chunks.

所以在你的例子中,你需要把你的代码分成两部分来处理。

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

#2


6  

In JavaScript, there is no concept of waiting or yielding. JavaScript continues execution, without interruption, of your code to its end. It seems weird and troublesome at first, but it has its advantages.

在JavaScript中,没有等待或屈服的概念。JavaScript将继续执行代码,而不会中断。一开始它看起来很奇怪,很麻烦,但是它有它的优点。

So the idea in scenarios such as this is that the code you wish to execute after receiving your response should be put into the callback that you give to FB.api(). You'll have to break out the code after your return statement into the response callback so that it can be executed when the response is received.

因此,在这样的场景中,您希望在接收到响应后执行的代码应该放在给FB.api()的回调中。您必须在返回语句之后将代码分解到响应回调中,以便在接收响应时执行它。

This is what you might expect from JavaScript if it were like most languages (such as C++/Java):

如果JavaScript像大多数语言(如c++ /Java)一样,您可能会期望它是这样的:

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

The idea in JavaScript, however, is based around callbacks when dealing with asynchrony:

然而,JavaScript的想法是基于在处理异步时的回调:

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

#3


0  

You don't want to prevent from returning it as doing such a thing will block the user's browser for the duration of the request. If the request hangs for whatever reason (congestion, site maintenance, etc...) the browser will become unresponsive to any user input resulting in upset users.

您不希望阻止它返回,因为这样做会在请求期间阻塞用户的浏览器。如果请求因任何原因(拥塞、站点维护等)而挂起,浏览器将对任何用户输入失去响应,从而导致用户不满。

Instead of doing the following:

而不是做以下的事:

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

Do this:

这样做:

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

makeCall();