【问题标题】:Setting timer after an asynchronous call returns在异步调用返回后设置计时器
【发布时间】:2012-03-01 08:47:29
【问题描述】:

我有一个异步 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) 可能需要一段时间才能完成,但我希望它在间隔 (1000 毫秒) 后执行相同的命令。

我想写一个这样的函数:

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调用返回后,另一个Ajax调用会X 秒后触发。

【问题讨论】:

  • 让我直说。您想用回调安排新的 ajax 调用每隔 X 秒触发一次,不管之前的 ajax 调用可能尚未完成,或者您想按顺序触发 ajax 调用(触发另一个上一个完成后)?
  • 我想在前一个 Ajax 调用完成后触发另一个 Ajax 调用。另外,值得一提的是,axashCallRepeated()会被各种参数调用,所以几个Ajax调用是并行运行的,但是对于每个commandStr,只有一个Ajax调用在进行,Ajax调用返回后,另一个Ajax调用会X 秒后被解雇。
  • 我会在第一个 Ajax 调用完成时触发一个自定义事件,然后执行第二个!

标签: javascript jquery ajax


【解决方案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 发布已完成并成功,现在您可以执行第二个。我知道这不是你问题的确切答案,但你应该考虑使用这样的东西!我猜它会更安全:-)

【讨论】:

  • 好主意,但您可能需要将其他数据传递给您的自定义事件(如我们示例中的命令)以了解已完成 ajax 调用的命令。
  • 我同意!但是我的回答应该被认为是对这样做的一种暗示,我认为他会认识到这一点:-)
  • 是的,我最近通过自定义事件来到这里!我还在某些项目中使用 setTimeout 来确保完成我的 ajax 调用,但这不是安全的方法,也没有干净的解决方案,所以不应该这样做,因为有更好的方法可以做到这一点:)
  • @EvilP:有趣的想法。我不知道 $(document).trigger() 但正如 WTK 所说,我有一些参数要传递给该函数。但是,似乎也可以将参数传递给 trigger():api.jquery.com/trigger 我想出了一个解决方案,我会写作为答案。
【解决方案2】:

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

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 天才能接受自己的答案。它有助于对其进行投票,以便它上升并且人们看到它有一个很好的答案。不过,我无法投票赞成我自己的答案。
【解决方案3】:

如果你把事情分开一点,推理会变得更容易。

例如,重复逻辑根本不需要了解 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();

【讨论】:

  • repeat() 每次调用 mkRepeater() 时对 interval、fn、fnScope、fnArgs 使用相同的值。我需要并行运行多个调用。
  • 你需要调用几个不同的调用,但是你需要错开它们?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
相关资源
最近更新 更多