【问题标题】:How to wait until Javascript forEach loop is finished before proceeding to next sep如何等到 Javascript forEach 循环完成后再继续下一个 sep
【发布时间】:2021-10-15 09:03:37
【问题描述】:

在调用另一个函数以重新加载应该由 axios 调用更新的数据之前,我需要等待由 forEach 循环调用的函数中的所有 axios 调用运行。

function1() {
    let arr = [1, 2, 3, 4, 5];
    arr.forEach((num) => {
        function2(num);
    });
    //Wait until each call in the forEach loop above
    //is done before running the function3() function.
    function3();
}

function2(number) {
    axios.post('/internal-url/action/' + number)
        .then((response) => {
            return response;
        });
}

function3() {
    console.log('reloading data...');
    /* DB call to reload data */
    console.log('data is reloaded');
}

这里的问题是数据在 axios 调用完成之前重新加载。我知道 axios 调用有效,因为我可以看到它们在数据库中更新,但我需要 function1() 等待 function2() 中的所有 axios 调用完成,然后再运行 function3() 中的重新加载。

我尝试过同时创建 function1()function2() async/await 函数,然后分别创建函数,但这不起作用。我该怎么做呢?

【问题讨论】:

  • forEach 不是异步的。你想要实现的是默认行为
  • 我并不特别了解 Axios,但在 JavaScript 中执行此类操作的通常方式涉及到在 AJAX 调用完成时调用的“回调”。例如,您可能有一个计数器,该计数器由foreach 循环(跟踪未完成请求的数量)递增,然后,在调用的回调中,从该计数器中减去 1 并测试为零。当它达到零时,你打电话给你的function3 ...

标签: javascript asynchronous foreach async-await axios


【解决方案1】:

创建一个承诺数组,然后使用Promise.all 等待它们的解决/拒绝使用async/await

// async/await - create an array of promises
// from function2, then await until Promise.all has
// fully resolved/rejected
async function1() {
  let arr = [1, 2, 3, 4, 5];
  const promises = arr.map((num) => function2(num));
  await Promise.all(promises);
  function3();
}

function2(number) {
  return axios.post('/internal-url/action/' + number);
}

function3() {
  console.log('reloading data...');
  /* DB call to reload data */
  console.log('data is reloaded');
}

【讨论】:

  • 这行得通。这真的很简单,并且可以让我做一些研究来真正理解它为什么/如何工作。
  • @aCarella:您可能想要使用const response = await Promise.all(promises);,然后对返回的response 数据(一个数组)执行一些操作。我没有在答案中添加它,因为不清楚你是否对它做任何事情。
【解决方案2】:

可能是这样的:

const arr = [1, 2, 3, 4, 5];
let index = 0;
const answers = [];
(function loop() {
    const value = arr[index];
    function2(value).then(res => {
        answers.push(res);
    });
    index++;
    if (index < arr.length) {
        loop();
    }
})();
function3();
console.log(answers);

【讨论】:

    【解决方案3】:

    最好的解决方案是使用Promise.all,这样所有请求都可以并行发出。这看起来像这样。

    function1() {
        let arr = [1, 2, 3, 4, 5];
        Promise.all(arr.map((num) => function2(num))).then(() => {
            function3();
        });
    }
    

    这将等到function2 返回的所有承诺都已解决,然后再调用function3

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多