JQuery - $.each 在 $.each 等待函数完成 [重复]

问题描述 投票:0回答:3

我有一个

$.each
循环,它在另一个
$.each
中,它正在调用一个函数来向我的后端系统添加值。

我的

$.each
循环是这样的:

$.each(locations, function( i, location ) { 
    $.each(location, function( i, site ) {
        addsite ( site.url, site.address, site.zip, site.contact, site.id )
    })
})

当我直接调用函数

addsites
时,而不是从
$.each
循环中它按预期工作,但是当从
$.each
循环中调用时它工作,但有时代码在其他代码完成之前被调用。

经过大量测试,我发现这是由于

$.ajax
被调用,这显然在其他代码运行之前没有完成。

我的工作职能是:

function addsite( url, address, zip, contact, id ) {
                
    // 1. lots of jquery
    // 2. lots of jquery
    
    $.ajax({ type: "POST",   
        url: url,
        cache: false,
        complete : function(text) {
            console.log ( '3.' + text )

        }
    });
    
    // 4. more jquery
})

我在第 1、2、3 和 4 点添加了调试,可以看到 1. 和 2. 中的所有内容都被正确调用,但是 4. 中的代码在

$.ajax
完成之前正在运行。

$.each
循环中调用该函数时,我在 console.log 中多次看到 1、2、4,后面跟着多个 3,因为它稍后会完成。这需要作为 1,2,3,4 运行。

我明白为什么会发生这种情况,并且发现将

async: false
添加到
$.ajax
允许这个工作,但它已经贬值所以我试图找到更好的方法。

我需要对

$.each
循环或
addsite
函数做些什么吗?如果它是函数,我需要确保它在直接调用时有效,而不仅仅是从
$.each
循环调用。

有人可以建议我如何才能让它正常工作。

谢谢

jquery ajax function each
3个回答
-1
投票

根据您的理解标准稍微更新一下代码:

$.each(locations, function( i, location ) { 
    $.each(location, function( i, site ) {
        addsite ( site.url, site.address, site.zip, site.contact, site.id, function() {
            
            console.log("AJAX request complete for " + site.id);
        });
    });
});

也在这个fn

function addsite( url, address, zip, contact, id, callback ) {

    $.ajax({ 
        type: "POST",   
        url: url,
        cache: false,
        complete : function(text) {
            console.log ( text );
            callback(); 
        }
    });
    
}

试试这个..


-1
投票

您可以使用 Promise 来确保 addsite 函数中的代码以正确的顺序运行。除了使用

complete
$.ajax
回调,您还可以返回一个 Promise,它会在 AJAX 调用完成时解析。然后,您可以使用
Promise.all
等待所有 AJAX 调用完成,然后再继续其余代码。

function addsite( url, address, zip, contact, id ) {
  // Return a Promise that resolves when the AJAX call is complete
  return new Promise(function(resolve, reject) {
    // lots of jquery

    $.ajax({
      type: "POST",   
      url: url,
      cache: false,
      success: function(response) {
        // Call resolve() when the AJAX call is successful
        resolve(response);
      },
      error: function(xhr, status, error) {
        // Call reject() when the AJAX call fails
        reject(error);
      }
    });

    // more jquery
  });
}

然后您可以使用 Promise.all 等待所有 AJAX 调用完成:

var promises = [];

$.each(locations, function( i, location ) { 
  $.each(location, function( i, site ) {
    // Add the Promise returned by addsite to the promises array
    promises.push(addsite(site.url, site.address, site.zip, site.contact, site.id));
  })
});

// Wait for all of the Promises to resolve before continuing
Promise.all(promises).then(function() {
  console.log("All AJAX calls complete");
}).catch(function(error) {
  console.log("An error occurred:", error);
});

-1
投票

很抱歉,我没有立即看到它不能在ajax请求中使用

async: false

现在在

for of
上重做循环并添加
async await
,做了一个测试用例:

const locations = [
  [
    {id: 1},
    {id: 2}
  ],
  [
    {id: 3},
    {id: 4}
  ]
];

const addsite = async( url, address, zip, contact, id ) => {
  console.log('before');
  await $.ajax({
    type: 'POST',   
    url: 'https://www.boredapi.com/api/activity',
    cache: false,
    complete : function(text) {
      console.log(id);
    }
  });
  console.log('after');
}

(async () => {
  for (let location of locations) {
    for (let site of location) {
      await addsite(site.url, site.address, site.zip, site.contact, site.id);
    }
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.