在函数完成JavaScript后继续在for循环中

continue in for loop after function is done JavaScript

本文关键字:for 循环 继续 JavaScript 函数      更新时间:2023-09-26

我发现了在 JavaScript 中让我遇到麻烦的行为。我有两个功能:

var show_uploaded = function( data_photo )获取有关上传照片的信息作为参数,


function exif_like(path){/*working with my image*/ console.log('exif_like END'); }这将获取每个上传照片的路径作为参数。

我做了这样的代码:

var show_uploaded = function( data_photo ){
    for( var z = 0; z < data_photo.length; z++ ){ 
       var send_image_name = uploaded_photo[z].name;
       $.ajax({
            data: { compare : send_image_name },
            url: 'get_panorama.php',
            method: 'POST', // or GET
            success: function( path ){
                exif_like( path );
                console.log('FOR LOOP END');
            }
       });
    }
};

但我在控制台中看到的是"FOR LOOP END"日志显示在"exif_like END"日志之前。这会导致我的代码中出现一些不可预测的行为。

有什么解决方案如何在 exif_like() 函数完成后继续循环吗?

如果其余进程返回预期结果,并且exif_like实际上只执行console.log()则可以尝试使用$.when()

$.when(exif_like( path )).then(function() {console.log("FOR LOOP END")})

如果你想让exif_like()在 Ajax 调用之间做一些事情,只需让你的exif_like()函数在下一个 Ajax 请求完成后调用它。

使用来自 json 占位符的测试数据,如下所示:

JavaScript

uploaded_photo = [{name: 1},{name: 2},{name: 6},{name: 8},{name: 9},{name: 11},{name: -1}]
pointer = 0;
function exif_like(path){
    /*working with my image*/ 
  obj = JSON.parse(path)
  if(obj.length > 0) {
    console.log(''t'tdata returned:'+obj[0].id + ' '+obj[0].title)
        console.log('exif_like END for '+obj[0].id);
  } else {
    console.log(''t'tNo data returned')
        console.log('exif_like END');  
  }
  /* Code here can be executed before the next Ajax call */
  console.log('Do stuff before the next ajax call...')
  pointer++;
  if(pointer < uploaded_photo.length) {
    show_uploaded();
  }
}
var show_uploaded = function(){
    console.log('---Start of Ajax call---');
  $.ajax({
    data: { id : uploaded_photo[pointer].name },
    url: 'https://jsonplaceholder.typicode.com/posts',
    method: 'GET', 
    complete: function( xhr ){
        console.log('---End of Ajax call---');
      exif_like( xhr.responseText );
    }
  });
};
show_uploaded()

输出

---阿贾克斯电话开始---
---阿贾克斯通话结束---
返回的数据:1 Sunt aut facere repellat provident occaecati excepturi optio reprehenderit
exif_like 结束 1
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
返回的数据:2 qui est esse
exif_like 结束 2
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
返回的数据:6 多洛伦 尤姆 马格尼 EOS 阿佩里亚姆 基亚
exif_like 结束 6
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
返回的数据:8 多洛伦 多洛尔东部 ipsam
exif_like 结束 8
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
返回的数据:9 nesciunt iure omnis dolorem tempora et accusantium
exif_like 结束 9
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
返回的数据:11 et ea vero quia laudantium autem
exif_like 结束 11
在下一次 ajax 调用之前做一些事情...
---阿贾克斯呼叫开始---
---阿贾克斯通话结束---
未返回
任何数据 exif_like结束

JS小提琴示例:https://jsfiddle.net/igor_9000/wwj11udx/3/

希望对您有所帮助!

*编辑:更新了代码以改用complete函数,以防请求不成功。

for loop替换为 while 循环,条件直到 data_photo 不为空,在开始之前while循环创建flag变量,该变量将是 ajax 成功处理程序完成的布尔标识符,下一个 ajax 可以发送。请参阅下面的代码,其中包含注释的更改:

var show_uploaded = function( data_photo ){
  // Create flag 
  var flag = true;
  var length = data_photo;
  // continue loop execution until data_photo not empty
  while (length){
    if(flag){
        var send_image_name = uploaded_photo[--length].name;
        // Set flag to false, until success executed
        flag = false;
        $.ajax({
            data: { compare : send_image_name },
            url: 'get_panorama.php',
            method: 'POST', // or GET
            success: function( path ){
                exif_like( path );
                console.log('FOR LOOP END');
                // We are ready to perform next ajax, set flag to true.
                flag = true;
            },
            error: function( path ){
                // Error or not we have to set flag to true to allow further iterating
                flag = true;
            }
       });
   }
}
};