如何让javascript代码按顺序执行*

Ed.*_*Ed. 20 javascript ajax order-of-execution

好的,所以我很欣赏Javascript不是C#或PHP,但我一直回到Javascript中的一个问题 - 不是JS本身,而是我使用它.

我有一个功能:

function updateStatuses(){

showLoader() //show the 'loader.gif' in the UI

updateStatus('cron1'); //performs an ajax request to get the status of something
updateStatus('cron2');
updateStatus('cron3');
updateStatus('cronEmail');
updateStatus('cronHourly');
updateStatus('cronDaily');

hideLoader(); //hide the 'loader.gif' in the UI

}
Run Code Online (Sandbox Code Playgroud)

事实上,由于Javascript强烈希望在代码中跳跃,加载器永远不会出现,因为'hideLoader'函数直接运行.

我怎样才能解决这个问题?或者换句话说,如何按照我在页面上写的顺序执行javascript函数...

ano*_*orm 15

出现此问题是因为AJAX本质上是异步的.这意味着updateStatus()调用确实按顺序执行,但立即返回,JS解释器hideLoader()在从AJAX请求中检索任何数据之前到达.

您应该hideLoader()在AJAX调用完成的事件上执行.


mea*_*gar 14

如果你正在进行AJAX编程,你需要将JavaScript视为基于事件而不是程序.您必须等到第一个调用完成后再执行第二个调用.这样做的方法是将第二个调用绑定到第一个调用完成时触发的回调.如果不了解AJAX库的内部工作原理(希望你使用的是库),我不能告诉你如何做到这一点,但它可能看起来像这样:

showLoader();

  updateStatus('cron1', function() {
    updateStatus('cron2', function() {
      updateStatus('cron3', function() {
        updateStatus('cronEmail', function() {
          updateStatus('cronHourly', function() {
            updateStatus('cronDaily', funciton() { hideLoader(); })
          })
        })
      })
    })
  })
});
Run Code Online (Sandbox Code Playgroud)

这个想法是,updateStatus采用它的正常参数,加上一个回调函数在它完成时执行.将函数传递给onComplete提供这种钩子的函数是一种相当常见的模式.

更新

如果你正在使用jQuery,你可以在$.ajax()这里阅读:http://api.jquery.com/jQuery.ajax/

您的代码可能看起来像这样:

function updateStatus(arg) {
  // processing

  $.ajax({
     data : /* something */,
     url  : /* something */
  });

  // processing
}
Run Code Online (Sandbox Code Playgroud)

您可以修改函数以将回调作为第二个参数,如下所示:

function updateStatus(arg, onComplete) {
  $.ajax({
    data : /* something */,
    url  : /* something */,
    complete : onComplete // called when AJAX transaction finishes
  });
Run Code Online (Sandbox Code Playgroud)

}


小智 10

我认为您需要做的就是在代码中使用它:

async: false,
Run Code Online (Sandbox Code Playgroud)

所以你的Ajax调用看起来像这样:

jQuery.ajax({
            type: "GET",
            url: "something.html for example",
            dataType: "html",
            async: false,
            context: document.body,
            success: function(response){

                //do stuff here

            },
            error: function() {
                alert("Sorry, The requested property could not be found.");
            }  
        });
Run Code Online (Sandbox Code Playgroud)

显然,一些这方面需要改变XML,JSON等等,但async: false,这里的要点,告诉JS引擎要等到成功的呼叫已恢复(或失败取决于)再进行.请记住,这有一个缺点,这就是整个页面变得反应迟钝,直到ajax返回!通常在几毫秒内这不是一个大交易,但可能需要更长的时间.

希望这是正确的答案,它可以帮助你:)


Pru*_*der 5

我们的一个项目中有类似的东西,我们通过使用计数器来解决它.如果你为每次调用增加计数器updateStatus并在AJAX请求的响应函数中减少它(取决于你正在使用的AJAX JavaScript库.)

一旦计数器达到零,所有AJAX请求都会完成,您可以调用hideLoader().

这是一个示例:

var loadCounter = 0;

function updateStatuses(){
    updateStatus('cron1'); //performs an ajax request to get the status of something
    updateStatus('cron2');
    updateStatus('cron3');    
    updateStatus('cronEmail');
    updateStatus('cronHourly');
    updateStatus('cronDaily');
}

function updateStatus(what) {
    loadCounter++;

    //perform your AJAX call and set the response method to updateStatusCompleted()
}

function updateStatusCompleted() {
    loadCounter--;
    if (loadCounter <= 0)
        hideLoader(); //hide the 'loader.gif' in the UI
}
Run Code Online (Sandbox Code Playgroud)

  • Ed,如果您喜欢这些解决方案之一,可以通过单击该人的答案旁边的复选框来标记您对最佳解决方案的选择吗? (3认同)