.forEach 完成后执行回调函数
Posted
技术标签:
【中文标题】.forEach 完成后执行回调函数【英文标题】:Executing a callback function after .forEach finishes 【发布时间】:2018-10-30 00:49:25 【问题描述】:我正在尝试在 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()
函数的部分。
我对胖箭头函数不太熟悉,所以错误可能来自它们的使用。
谁能解释为什么脚本没有按预期运行?
【问题讨论】:
当你调用它时,你将一个函数作为第二个参数传递给asyncFunction()
,但函数声明不期望第二个参数,并且永远不会调用传递给它的回调
有道理,谢谢。但是我不确定要声明哪个参数。显然asyncFunction(item, ())
不起作用。您能否更明确地解释如何处理第二个论点?
【参考方案1】:
在这种情况下,更现代的方法是使用 Promise
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
【讨论】:
先生。查理,非常感谢!我从这个 sn-p 中学习并继续我的任务。在这个我们不能见面和握手的虚拟世界里。愿你得到我的善报。【参考方案2】:因为您想将回调函数作为第二个参数传递给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);
);
【讨论】:
【参考方案3】:将每个元素映射到一个 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
构造函数而不是异步函数。
【讨论】:
以上是关于.forEach 完成后执行回调函数的主要内容,如果未能解决你的问题,请参考以下文章
promise核心技术 2.两种回调函数 js中error的处理