2014-01-28 106 views
1

我有一個函數,它有一個$ .each循環遍歷一個對象的鍵並執行一些操作。在這個循環中,我調用了一個函數,這個函數反過來調用服務器來獲取一些數據,並在回調中對它進行處理。這些調用是異步的,因此$ .each不會等待數據到來,並且回調會執行它應該保持迭代的操作。我如何使$ .each循環等待,直到我完成我的操作,然後繼續。

$.each(messages,function(key) { 
//do something 
if(some Condition) { 
getfromserver(token,myCallback); } 
//do something 
}); 




function myCallback(data) 
{ 
    //do something with data 
} 
+0

那麼你最好不要使用各... – epascarello

+0

@epascarello會用「爲」解決這個問題? – vijar

+0

'每個'都不是爲你想要的而構建的,但是作爲一個複製鏈接的問題上提到的函數都是你所需要的。而且,當我們進入下一個版本的Javascript時,[這種機制將成爲語言的本地部分](http://www.html5rocks.com/en/tutorials/es6/promises/) –

回答

0

你不能用簡單的迭代。相反,你應該這樣做:

function unqueue() { 
    if (!messages.length) 
    return; 
    var key = messages.pop(); 
    // do something 
    getfromserver(token, myCallback); 
    //do something 
} 

function myCallback(data) { 
    //do something with data 

    // Repeat it until messages is not empty 
    unqueue(); 
} 

unqueue(); 
+0

-1不解決OP詢問的問題。這不等待服務器IO在請求下一個之前完成。 – Peter

+0

我認爲回調位於getfromserver之後的行。我編輯了我的答案。 – gtournie

+0

+1看起來不錯,刪除了我的倒票:) – Peter

1

你可以做的,而不是$.each這一點,我把它叫做回調循環:

iterate(messages, 0); 

function iterate(arr, i) { 
    if(i==arr.length) return; 
    var message = arr[i]; 
    //you might want to create your token based on current message 
    var token = "..."; 

    if(/*some Condition*/){ 
     getfromserver(token, function (data) { 
      myCallback(data); 
      iterate(arr, i++); 
     }); 
    } 
    //use this else if you want to do something like 'continue' 
    //and don't use it if it kinda 'break' 
    else iterate(arr, i++); 
} 

function myCallback(data) { 
    //do something with data 
} 
0

加入循環到你的回調基本思路

var messages = {foo:"1","bar":2,"asdf":3}; 
var keys = $.map(messages, function(val, key) { return key}); 

function makeCall() { 
    if(!keys.length) return; 
    var next = keys.shift(); 
    var token = messages[next]; 
    getfromserver(token,myCallback); 
} 

function myCallback(data) 
{ 
    //do something with data 
    makeCall(); 
} 

有很多建立呼叫隊列的方法。

0

這是coffeescript,但我認爲它可以滿足你的需求。你不斷向前投擲執行到一個函數,很像的NodeJS:

processMessages = (messages, callback, args) -> 
    # End it by returning the callback result when messages are done 
    return callback() unless messages.length 

    # Shift the first message off the list 
    message = messages.shift() 

    # Send it to the server for something to do 
    $.ajax 
     url: '/echo/json/' 
     method: 'POST' 
     data: 
      json: JSON.stringify({ message: message, args: args }) 
     dataType: 'json' 
     success:(data) -> 
      # Respond to the server's response 
      console.log 'Got ' + data.message 

      # Process the remaining messages 
      processMessages messages, callback, args 

finished = -> 
    console.log 'all done here' 

processMessages ['hi', 'bob'], finished, 'yo' 

的CoffeeScript:http://jsfiddle.net/datashaman/22gDa/3/

的Javascript叉:http://jsfiddle.net/datashaman/3zdQ8/1/

相關問題