代码之家  ›  专栏  ›  技术社区  ›  senty

foreach,等待每次迭代直到接收到响应(使JS同步)

  •  0
  • senty  · 技术社区  · 5 年前

    我有一个foreach循环,我在迭代元素。对于每个元素,我使用Ajax将其保存到数据库中。但是,我希望每个迭代都等待,直到前一个迭代保存到数据库中并收到响应。

    让我给你一个简单的例子:

    $('#myBtn').click(function() {
       let elements = $('.checkboxes:checked');
    
       elements.forEach(function(i, el) {
          let id = $(el).data('id');
    
          saveToDatabase(id);
          // I want it to pause here until it receives a response from other function 
          // before going to the next iteration..
       })
    
    })   
    
    
    function saveToDatabase(id) {
       axios.get('/save-to-db/' + id)
           .then(response => {
               return true;
           }).catch(err => {
               return false;
       });
    }
    

    我希望在从中获得“返回”后,forach的元素移到下一个迭代 saveToDatabase 功能。

    (顺便说一下,我知道这个例子过于简单,在现实生活中没有意义,因为我可以将ID批量保存到数据库中,但是我只是想了解如何处理这种情况)。

    3 回复  |  直到 5 年前
        1
  •  1
  •   senty    5 年前

    定义 saveToDatabase(id) 作为异步函数,在本例中使用 await .

    参考文献: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

    编辑: 此外,还应向 saveToDabase 功能。

    savetodatabase函数的实现:

    $('#myBtn').click(function() {
       let elements = $('.checkboxes:checked');
    
       for (let element of elements) {
           await saveToDatabase(id);
       }
    }) 
    
    async function saveToDatabase(id) {
       return axios.get('/save-to-db/' + id)
           .then(response => {
               return true;
           }).catch(err => {
               return false;
       });
    }
    

    我也忘了: 在其中使用wait的函数,也需要前面有async。

        2
  •  1
  •   Kevin Pastor    5 年前

    自从 forEach 使用回调函数,很难一直使用它来同步调用。相反,我认为使用 for 循环将工作。

    $('#myBtn').click(async () => {
        let elements = $('.checkboxes:checked');
        for (let element of elements) {
            let id = $(element).data('id');
            await saveToDatabase(id);
        }
    });
    
        3
  •  0
  •   Maksim Romanenko    5 年前

    有很多方法可以让请求彼此等待。对您来说,最简单的方法是保存最新请求的引用,承诺在上次解决时调用下一个请求(内部 then 功能)。

    $('#myBtn').click(function() {
       let elements = $('.checkboxes:checked');
       let previousCall = Promise.resolve();
    
       elements.forEach(function(i, el) {
          let id = $(el).data('id');
    
          previousCall = previousCall.then(() => saveToDatabase(id));
          // I want it to pause here until it receives a response from other function
          // before going to the next iteration..
       })
    
    })   
    
    
    function saveToDatabase(id) {
       return axios.get('/save-to-db/' + id)
           .then(response => {
               return true;
           }).catch(err => {
               return false;
       });
    }