2012-05-08 105 views
0

我正在與更改和保存外部文件的servlet進行通信。由於這需要一些時間,我需要一些JavaScript函數調用順序發生,以便一個函數的動作不會干擾另一個函數的動作。順序函數調用

爲此,我編寫了一個「順序」函數,它接受另一個函數,該函數只能在busyflag設置爲false(即,沒有其他函數調用同時處理)時才能調用。這是我的代碼:

var busy = false; 
function sequential(action) { 
    while(busy) 
     setTimeout(function(){sequential(action);}, 10); 
    busy = true; 
    action(); 
    setTimeout(function(){busy = false;}, 100); 
} 

function test1() {sequential(function() {alert("test1");});} 
function test2() {sequential(function() {alert("test2");});} 

而且this上的jsfiddle的例子。出於某種原因,此代碼在第二次調用時保持循環(當函數調用必須等待時)。

+0

我想你可能會發現[deferreds(http://api.jquery.com/category/deferred-object/)有用... – elclanrs

回答

0

我第一次實現像詹姆斯·蒙塔涅提出了一個解決方案,但一些Searchin的後,我發現,你可以使用的onreadystatechange屬性XMLHttprequest將busy-flag設置爲true。

此代碼的工作像預期:

function sequential(action) { 
if (busy) setTimeout(function(){sequential(action);}, 20); 
else action(); 
} 

function send(message){ 
    busy = true; 
    var request = new XMLHttpRequest(); 
    request.open("POST", "owlapi", true); 
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    request.send(message); 
    request.onreadystatechange = function() {busy = false;}; 
} 
1
while(busy) 
     setTimeout(function(){sequential(action);}, 10); 

setTimeout不會阻塞,它立即返回並允許循環繼續。 Javascript是單線程的,所以這個循環只是保持運行,並且阻止任何其他代碼執行,這意味着繁忙永遠不會被設置爲false來退出循環。

假設你正在等待的這些東西是ajax調用,你可能會想要使用某種類型的隊列,然後在調用ajax的回調中,運行下一個請求。

1

我認爲你的JavaScript正在對你的服務器進行ajax調用。

如果您需要不同的調用來一個接一個地運行,那麼您應該讓您的JavaScript代碼設置掛鉤,以便在發出下一個請求之前等待從一次調用返回結果。

爲了達到這些目的,我推薦使用一個JavaScript工具包,如jQuery。它使得這樣的問題更容易解決。 jQuery中的每個ajax方法都至少接受一個將在查詢完成時調用的回調函數。對於jQuery.ajax()你可以去

$.ajax(...).done(function() { 
    // This part will be run when the request is complete 
}); 

而對於.load()

$("#my_element").load(url,data,function() { 
    // This part will be run when the request is complete 
});