2012-06-12 35 views
6

điều tôi đã gặp khó khăn trong quá khứ và đang gặp khó khăn với hôm nay đang ngăn không cho API/AJAX tiếp tục cho đến khi bạn nhận được phản hồi của mình. hiện tôi đang làm việc với API Facebook. Tôi cần nhận được phản hồi từ một cuộc gọi rồi trả lại cuộc gọi nhưng những gì đang xảy ra là chức năng của tôi sẽ trở lại trước khi tôi nhận được phản hồi từ cuộc gọi API. Tôi biết tại sao nó xảy ra, tôi không thể tìm ra cách ngăn chặn nó! Dưới đây là mã của tôi ...Đang chờ lệnh gọi API kết thúc bằng Javascript trước khi tiếp tục

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

tôi nhận thấy một số người đề nghị một cái gì đó như thế này ...

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

Nhưng điều này trả về undefined

// CHỈNH SỬA DỰA TRÊN CẬP NHẬT

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

Tôi tin rằng vì 'return finalresponse;' nằm ngoài cuộc gọi API. –

+0

sự trở lại của bạn sẽ thực thi trước khi FB.api hoàn thành – Dhiraj

+0

mã bạn cung cấp trong bản chỉnh sửa của mình không chính xác. Trả về finalResponse trong cuộc gọi lại của bạn sẽ được trả lại cho người gọi về cuộc gọi trả lời của bạn. Lý do không xác định được trả về cho người gọi cho makeCall() là bởi vì thực hiện cuộc gọi không trả lại bất cứ điều gì. –

Trả lời

13

Câu hỏi được hỏi 100 lần một ngày và dường như không thể có một câu trả lời.

Cuộc gọi không đồng bộ nên không thể thực hiện điều đó trong một bước. Ví dụ cơ bản về những gì bạn mong đợi.

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

gì đang thực sự xảy ra:

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

Những gì bạn cần làm là chia nó ra thành hai phần.

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

Vì vậy, trong trường hợp của bạn, bạn cần phải chia nhỏ mã để xử lý theo hai khối.

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

Và @Pointy vừa giết bản chỉnh sửa của tôi, thời gian để làm lại nó một lần nữa. – epascarello

+0

Cảm ơn, điều này thực sự đã giúp tôi hiểu nhưng nếu tôi muốn trả lời câu trả lời cho cuộc gọi ban đầu thì sao? Xem chỉnh sửa cuối cùng của tôi ở trên. Tôi muốn lấy giá trị và trả lại. Vì vậy, về cơ bản tôi có một chức năng mà gọi share_share và nó cần phải được trả lại với một phản ứng. –

+0

Nó không thể được trả lại, nó phải được gọi lại. 'Return finalresponse;' là điều tương tự bạn có trước đó, chỉ theo một cách khác! – epascarello

6

Trong JavaScript, không có khái niệm về việc chờ đợi hoặc sinh lời. JavaScript tiếp tục thực thi, mà không bị gián đoạn, mã của bạn sẽ kết thúc. Nó có vẻ kỳ lạ và rắc rối lúc đầu, nhưng nó có lợi thế của nó.

Vì vậy, ý tưởng trong các trường hợp như vậy là mã bạn muốn thực thi sau khi nhận được phản hồi của bạn nên được đưa vào hàm gọi lại mà bạn cung cấp cho FB.api(). Bạn sẽ phải giải mã ra sau khi câu lệnh return của bạn trả về callback response để nó có thể được thực thi khi nhận được phản hồi.

Đây là những gì bạn có thể mong đợi từ Javascript thể nó là giống như hầu hết ngôn ngữ (chẳng hạn như C++/Java):

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

Ý tưởng trong JavaScript, tuy nhiên, được dựa trên callbacks khi giao dịch với sự không đồng bộ :

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

cảm ơn thời gian của bạn, bạn có đề xuất nào để thực hiện việc này không? –

+0

Tôi đã thêm một ví dụ để làm rõ ý tưởng. –

0

Bạn không muốn ngăn không trả lại khi làm như vậy sẽ chặn trình duyệt của người dùng trong thời gian yêu cầu. Nếu yêu cầu bị treo vì bất kỳ lý do gì (tắc nghẽn, bảo trì trang web, v.v ...), trình duyệt sẽ không phản hồi cho bất kỳ đầu vào nào của người dùng dẫn đến người dùng khó chịu.

Thay vì làm như sau:

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

Làm điều này:

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

makeCall(); 
Các vấn đề liên quan