在循环中调用异步函数时避免重复创建函数

Posted

技术标签:

【中文标题】在循环中调用异步函数时避免重复创建函数【英文标题】:Avoiding repetitive creation of functions when calling async functions in loop 【发布时间】:2014-03-21 19:06:38 【问题描述】:

有没有办法在不创建匿名函数 10 次的情况下执行以下操作? 假设 setTimeout 只需要 2 个参数,回调和间隔。据我所知,您不应该在循环中创建函数,因为它很慢。但是,如果异步函数不允许您向其传递您希望回调知道的参数,是否可以避免这样做?注意:我知道在 Chrome 中 setTimeout 需要更多参数,所以这不是一个理想的例子。

function doSomethingAsync(i)
    setTimeout(function()  //This anonymous function is created 10 times
        console.log(i);
    , 1000);


for (var i = 0; i < 10; i++) 
    doSomethingAsync(i);

【问题讨论】:

看看this answer,因为它可能会为您提供见解。您可以将参数转换为函数对象的属性。 @mathielo 这绝对很有趣,但我仍然不清楚如何应用这个想法(特别是因为对该答案的评论表明,如果你这样做,你将失去创建函数的好处路线)。 好吧@AlexMA,如果您打算在 IE 上运行您的代码,您可以试试这个other approach。这不是最好的解决方案,因为它不是完全跨浏览器,但在某些情况下它可能会有所帮助。 @mathielo 我并不真正关心 setTimeout,它只是“限制性”异步函数的一个示例。 【参考方案1】:

简短回答 - 。如果您想匹配每个迭代的值以映射回来,就像您在这里所做的那样。我不会在这里评论性能,而是首先关注需求。

如果您不关心映射到正确调用的值,那么您可以避免简单地创建函数

javascript 引擎已经允许这样的情况。这适用于不必定义多个匿名函数。这是通过向回调提供有关当前执行的更多信息来实现的,即eventobject。这就是 DOM、XHR、html5 文件 API 等相互交互的方式。因此,理想情况下,这意味着 Javascript 上下文之外的东西正在调用具有所需信息的 Javascript 方法。

浏览器或者更确切地说是 JS 引擎应该提供一种机制来为回调策略预定义某种eventobject,因此一个function 可以处理所有callbacks。 AFAIK,除了创建小的函数闭包之外,目前没有办法在 JS 本身中做同样的事情。所以我们得等到有消息再说。

希望这有助于阐明这一点。

更新 - 刚刚看到有关问题的注释,删除了不必要的代码。

【讨论】:

【参考方案2】:

这个特定示例有一种方法,使用eval()。我不会争论你是否应该使用它,但是......

你可以像这样重写你的例子:

function doSomethingAsync(i)
    setTimeout("console.log(" + i + ");", 1000);


for (var i = 0; i < 10; i++) 
    doSomethingAsync(i);

将字符串传递给 setTimeout 对经过时间后传入的字符串执行 eval() 的等效操作。

【讨论】:

【参考方案3】:

为了给出你想要的相同结果,我会使用递归:

var i = 0; 
doSomethingAsync();
function doSomethingAsync()

i = i +1; 
console.log(i);
if (i<10) setTimeout(doSomethingAsync,500);

【讨论】:

以上是关于在循环中调用异步函数时避免重复创建函数的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中的类构造函数中调用异步方法 [重复]

进阶学习5:JavaScript异步编程——同步模式异步模式调用栈工作线程消息队列事件循环回调函数

python中for循环中的异步作业[重复]

使用 setInterval() 的无限异步循环 [重复]

如何在.NET中调用异步函数而不等待它[重复]

从构造函数调用的异步方法[重复]