在等待ajax时,为每个循环暂停a.完成完成


Pausing a for each loop while waiting for ajax.done to complete

我正在使用for每个方法遍历命令文件数组。

对于每个命令文件,我需要等待ajax成功,然后再继续执行下一个命令。

问题在于,在ajax代码完成之前,for循环会转到下一个命令。有人能提供解决方案吗?

对于每个循环:

$.each(cmd_files, function(index, cmd) {
          update_log('Running CMD for' + cmd)
          wait_for_cmd_complete(cmd).done(function(data){
               update_log("CMD is complete");    
          })
 })
Ajax功能:

function wait_for_cmd_complete(cmd){
     return $.ajax({
         type: 'POST',
         data: {cmd:cmd}, 
         url: 'wait_for_cmd_complete.php'
     });  

  }

这不是编写事件驱动操作的方式。如果你需要下一次代码迭代只在一个事件之后开始,那么你就不需要循环遍历迭代……因为这将在事件发生之前运行所有的代码!这就是事件的运作方式。

创建类似这样的通用结构将更好地为每个事件运行一次代码迭代:

var i = 0; // the index we're using
var list = []; // array of the things you plan on "looping" through
var max = list.length; // basically how many iterations to do
function nextIteration() {
    if (i >= max) return; // end it if it's done
    // do whatever you want done before the event for this iteration
    list[i].addEventListener("someevent", onEvent); // add whatever event listener
}
function onEvent() {
    // do whatever it is you want done after the event for this iteration
    i++; // up the index
    nextIteration(); // start the next iteration
}
nextIteration(); // start the first iteration manually

为了便于说明,你可以知道发生了什么,这里是你的代码格式像我上面的代码。

var i = 0; // the index we're using
update_log('Running CMDs');
var cmd; // basically a var just so we don't have to keep calling cmd_files[i]
var totalCommands = cmd_files.length; // basically how many iterations to do
function sendNextCommand() {
    if (i >= totalCommands) return; // end it if it's done
    cmd = cmd_files[i]; // again, just so we don't have to keep calling cmd_files[i]
    update_log("Waiting for CMD " + cmd + " to complete...");
    $.ajax({type:'POST', data:{cmd:cmd}, url:'wait_for_cmd_complete.php'}).done(onCommandComplete);
    // above line does what needs to be done (sends to PHP) and then adds the event listener 'done'
}
function onCommandComplete(value) {
    update_log( "    CMD complete for: " + cmd);
    i++; // up the index
    sendNextCommand(); // start the next iteration
}
sendNextCommand(); // start the first iteration manually

这就是我最后的工作。

  1. 第一个Ajax请求完成。

  2. cmd文件数组使用i++进行升级。

  3. Ajax函数在同一个函数中被再次调用。

  4. 如果还有更多的文件要运行,函数被再次调用,

  5. else函数在最后一个cmd文件完成后退出。

     number_of_cmd_files = cmd_files.length;
     update_log('Running CMDs')
     i=0;
     cmd= cmd_files[i];
     wait_for_cmd_complete(cmd)
     function wait_for_cmd_complete(cmd){
        update_log("Waiting for CMD " + cmd + " to complete...")
       $.ajax({
            type: 'POST',
            data: {cmd:cmd}, 
            url: 'wait_for_cmd_complete.php'
        }).done(
             function(value) {
             i++;  
             update_log( "    CMD complete for: " + cmd);
             if (i < number_of_cmd_files) {
               cmd = cmd_files[i]
               wait_for_cmd_complete(cmd);  
             }
           }
        ); 
    

    }

也许可以尝试链接您的事件。不太熟悉这种方法,但我认为这将工作:

$.each(cmd_files, function(index, cmd) {
            update_log('Running CMD for' + cmd);
            var request =  $.ajax({type: 'POST',data: {cmd:cmd}, url: 'wait_for_cmd_complete.php'});
            request.then( update_log("CMD is complete");        
 });

使用同步ajax应该可以工作,至少如果您不跨域使用的话。将async: false添加到ajax选项中。