顺序函数调用

sequential functioncalls

本文关键字:函数调用 顺序      更新时间:2023-09-26

我正在与一个更改并保存外部文件的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上的例子。出于某种原因,这段代码在第二次调用时(当函数调用必须等待时)一直循环。

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

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

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

我认为你的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
});

我首先实现了 James Montagne 建议的解决方案,但经过一些搜索,我发现您可以使用 XMLHttprequest 的 onreadystatechange 属性将 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;};
}