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

这是jsFiddle上的示例。由于某种原因,这段代码在第二次调用时不断循环(当函数调用必须等待时)。

4

3 回答 3

1
while(busy)
        setTimeout(function(){sequential(action);}, 10);

setTimeout不阻塞,它立即返回并允许循环继续。Javascript 是单线程的,所以这个循环只是保持运行并阻止任何其他代码执行,这意味着busy 永远不会被设置为 false 以退出循环。

假设您正在等待的这些事情是ajax调用,您可能希望使用某种队列,然后在调用的回调中ajax运行下一个请求。

于 2012-05-08T19:40:10.507 回答
1

我认为您的 javascript 正在对您的服务器进行 ajax 调用。

如果您需要不同的调用一个接一个地运行,那么您应该让您的 javascript 代码设置挂钩,以等待它从一个调用返回结果,然后再发出下一个请求。

为了这些目的,我建议使用jQuery之类的 javascript 工具包。它使这样的问题更容易解决。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
});
于 2012-05-08T19:40:40.130 回答
0

我首先实现了 James Montagne 建议的解决方案,但经过一番搜索后,我发现您可以使用 XMLHttprequest 的 onreadystatechange 属性将忙标志设置为 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;};
}
于 2012-05-09T09:47:38.177 回答