在.forEach完成后执行回调函数

时间:2018-05-20 00:19:45

标签: javascript foreach callback

我正在尝试在forEach循环完成所有迭代后执行一个函数。

这个answer提供了一个有趣的解决方案,但我无法让它发挥作用。

这是我改编的代码,创建了一个简单的asyncFunction()。

function callback () { console.log('all done'); }
function asyncFunction(item) {
  console.log("in async function, item is " + item)
}
var itemsProcessed = 0;

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

在此JSfiddle中可见,脚本正确执行异步功能,但无法输入增加itemsProcessed并应触发callback()功能的部分。

我不太熟悉胖箭头功能,所以错误可能源于它们的使用。

有人可以解释为什么脚本没有按预期运行吗?

3 个答案:

答案 0 :(得分:2)

这是一种更现代的方法是使用承诺

的情况



function asyncFunction(item) {
   // return a promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("in async function, item is " + item)
      // resolve promise when data is ready
      resolve(item)
    }, Math.random()*2000)// random delay to stagger order of returns

  })

}

// create array of promises
let promiseArray = [1, 2, 3].map(asyncFunction);

// runs when all promises are resolved
Promise.all(promiseArray).then(results => {
  console.log('all done')
  // results array will be in same order as original array
  console.log('results are: ', results)
})

.as-console-wrapper {max-height: 100%!important;top:0}




答案 1 :(得分:1)

将每个元素映射到Promise,然后使用Promise.all()

Promise.all([1, 2, 3].map(async num => num));

当然,如果需要,你可以在异步函数内部做一些更复杂的事情。

Promise.all([1, 2, 3].map(num => 
{
    return new Promise((reject, resolve) =>
    {
        setTimeout(() => resolve(num), 5000);
    })
}));

如果您执行的代码是同步的或涉及超时,则使用Promise构造函数而不是异步函数。

答案 2 :(得分:0)

因为你想将一个回调函数作为第二个参数传递给asyncFunction,你需要指定那里的回调函数是第二个参数,你需要这样调用:

function asyncFunction(item, cb) {
  console.log("in async function, item is " + item)
  cb()
}

此外,您的代码可以重写,以便更容易理解回调函数的使用。你的代码:

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

与:

相同
[1, 2, 3].forEach((item, index, array) => {
  function cbFunc() {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  }
  asyncFunction(item, cbFunc);
});