Waiting for an API call to complete in Javascript before continuing

what I struggled with in the past, and am struggling with today, does not allow the API / AJAX to continue until you get a response. I am currently working with the Facebook API. I need to get the response from the call and then return it, but what happens is that my function returns before I receive the response from the API call. I know why this is happening, I just can't figure out how to prevent this! Here is my code ...

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 that 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 ON THE BASIS OF UPDATE

 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); } 
+6
source share
3 answers

A question asked 100 times a day and it seems impossible to get one answer.

The call is asynchronous, so it cannot be done in one step. A basic example of what you expect.

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

What is actually going on:

 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 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 need to break your code in order to process it in two pieces.

 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); 
+13
source

JavaScript has no concept of expectation or concession. JavaScript continues to execute, without interrupting, your code to the end. At first it seems strange and unpleasant, but it has its advantages.

So the idea in scripts like this is that the code you want to execute after receiving the response should be placed in the callback you pass to FB.api (). You will have to wrench the code after the return statement in the response so that it can be executed when the response is received.

This is what you can expect from JavaScript if it was like most languages ​​(like C ++ / Java):

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

However, the idea in JavaScript is based on callbacks when working with asynchrony:

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

You do not want to prevent it from being returned, since such an action blocks the user's browser for the entire duration of the request. If the request freezes for some reason (congestion, site maintenance, etc.), the browser stops responding to any user requests, which leads to user disruption.

Instead of doing the following:

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

Do it:

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

Source: https://habr.com/ru/post/917903/


All Articles