2012-05-08 73 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 
});