异步调用返回后设置定时器

时间:2012-03-01 08:47:30

标签: javascript jquery ajax

我有一个异步Ajax函数,它在服务器端运行命令字符串并将结果返回给客户端。它调用回调来处理结果。

function ajaxCall(commandStr,callback){
   var url=......//make a url with the command string
   jquery.get(url,function(result){
       //process the result using callback
       callback(result);
   });
}

异步调用(ajaxCall)可能需要一段时间才能完成,但我希望它在一个间隔(1000ms)之后执行相同的命令。

我想写一个这样的函数:

function ajaxCallRepeated(interval,commandStr,callback)

我试过像这样的闭包:

function ajaxCallRepeated(interval,commandStr,callback){
    //This feature uses closures in Javascript. Please read this to know why and how: http://jibbering.com/faq/notes/closures/#clSto
    function callLater(param1,param2,param3){
        return (function(){
            ajaxCall(param2,function(out,err){
                if(param3)param3(out,err);
                var functRef = callLater(param1,param2,param3);
                setTimeout(functRef, interval);
            });
        });
    }
    //the first call
    var functRef = callLater(interval,commandStr,callback);
    setTimeout(functRef, interval);
}

然后我称之为:

ajaxCallRepeated(2000,"ls",function(result){
    alert(result);
});

但它只运行命令2次。 如何在调用异步函数的回调函数后编写一个重新调度自身的函数?

PS。我想在上一个Ajax调用结束后再触发另一个Ajax调用。此外,值得一提的是,axashCallRepeated()将使用各种参数调用,因此几个Ajax调用并行运行,但是对于每个commandStr,只有一个Ajax调用正在进行,并且在Ajax调用返回后,另一个将在X秒后被解雇。

3 个答案:

答案 0 :(得分:1)

我不会使用setTimeout来触发第二个Ajax调用!因为你永远不知道需要多长时间以及它是否已经完成!  至于你正确标记你的问题并且你正在使用jquery,你应该考虑这样的事情:

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: function(){
    // The AJAX is successfully done, now you trigger your custom event:
    $(document).trigger('myAjaxHasCompleted');
  },
  dataType: dataType
});

$(function(){
    //somehwere in your document ready block
    $(document).on("myAjaxHasCompleted",function(){
        $.ajax({
            //execute the second one
        });
    });
});

因此,这将确保ajax帖子完成并且成功,现在您可以执行第二个。我知道它不是你问题的确切答案,但你应该考虑使用这样的东西!我认为会更安全: - )

答案 1 :(得分:0)

解决此问题的关键是保存对闭包本身的引用,并在安排下一次调用时使用它:

function ajaxCallRepeated(interval,commandStr,callback){
    //This feature uses closures in Javascript. Please read this to know why and how: http://jibbering.com/faq/notes/closures/#clSto
    function callLater(_interval,_commandString,_callback){
        var closure=(function(){
            ajaxCall(_commandString,function(out,err){
                if(_callback)_callback(out,err);
                setTimeout(closure,_interval);
            });
        });
        return closure;
    }
    //now make a closure for every call to this function
    var functRef = callLater(interval,commandString,callback);
    //the first call
    functRef();
}

答案 2 :(得分:0)

如果你把事情分开一点,就更容易推理了。

例如,重复逻辑根本不需要知道AJAX或回调:

function mkRepeater(interval, fn, fnScope, fnArgs) {
  var running;

  function repeat() {
    if (!running) return;
    fn.apply(fnScope, fnArgs);
    setTimeout(repeat, interval);
  }

  return {
   start: function() { running = true; repeat(); },
   stop: function() { running = false; }
  };
}

你可以像这样使用它:

var r = mkRepeater(2000, ajaxFunction, this, ["getStuff", callbackFn]);
r.start();
...
r.stop();