2012-06-12 228 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; 

} 

// -----編輯

我注意到有些人認爲這樣的事情...

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

但這返回undefined

//根據更新編輯

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將返回給您的回覆回調的調用者。未定義的原因返回給makeCall()的調用者是因爲make call沒有返回任何東西。 –

回答

13

被要求每天100次,似乎不可能有一個答案的問題。

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

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

你需要做的是把它分解成兩個部分。

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

所以在你的情況下,你需要分解你的代碼來處理它在兩個塊。

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

它不能只是返回,它必須是回調。 「迴歸最終答案」與以前一樣,只是以不同的方式! – epascarello

6

在JavaScript中,沒有等待或屈服的概念。 JavaScript將繼續執行,而不會中斷代碼的執行。起初看起來很奇怪和麻煩,但它有其優點。

因此,在這種情況下的想法是,您希望在收到您的響應後執行的代碼應放入您給FB.api()的回調中。您必須在返回語句之後將代碼分解爲響應回調,以便在收到響應時執行它。

這就是你可能期望從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 
}); 
+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(); 
相關問題