asynchronous调用NodeJS中的asynchronous响应

我现在正在用NodeJS构build我的第一个项目,但是我对这个任务有点困惑,我认为这是一个简单的问题,我想问题是我对这些asynchronous方法缺乏了解,但是我无法在任何地方find答案。

我有一个简单的循环遍历数组和任何元素,根据一些规则,我会调用一个函数或另一个。 现在一些操作会比其他操作更快,所以我最终可能会返回元素N上的函数,而不是元素N-1上的函数。 为了使它像这样简单

for (var i = 0 ; i < 10 ; i++) { if (i%2 === 0) { setTimeout(function(i) { console.log(i); }, 2000); } else { console.log(i); } } 

所以任何偶数都会打印2秒,而奇数将被立即打印。 无论如何,运行它我得到

 1 3 5 7 9 <<2 seconds break>> undefined undefined undefined undefined undefined 

看起来偶数值是“迷失”。 我怎样才能通过这个值确保函数不会丢失input值? 我错过了什么吗?

谢谢,毛罗

你的setTimeout参数函数被声明为一个参数, i 。 当setTimeout调用没有参数的函数时,参数被设置为undefined

这似乎是稍微好一点,因为它不再影响你最初试图引用的外部variables…

 setTimeout(function() { console.log(i); }, 2000) 

…但如果你运行它,你会发现它打印10 5次,因为你创build的每个函数引用相同的ivariables,当循环退出条件变为true并且它终止时,它的值将是10

创build一个闭包 ,它保存了i在创buildsetTimout参数函数的循环过程中的值,

 setTimeout((function(i) { return function() { console.log(i); } })(i), 2000) 

将参数重命名为我们刚刚使用的“ 立即调用函数expression式”可能有助于使事情变得更加清晰:

 setTimeout((function(loopIndex) { return function() { console.log(loopIndex); } })(i), 2000) 

我们是:

  • 创build一个接受一个参数并返回另一个函数的函数。
  • 立即调用“外部”函数,传递它的当前值(这不是一个对象,所以有效地通过值)。
  • “外部”函数返回“内部”函数,它作为parameter passing给setTimeout

这是因为:

  1. 在JavaScript中创build一个函数会创build一个新的范围来保存函数的参数variables以及其中使用var关键字在其中声明的任何其他variables。 把它想象成一个不可见的对象,其属性对应于variables名称。

  2. 作为其范围链的一部分,所有函数都会引用它们被定义的范围 。 他们仍然可以访问这个范围,即使它不再是“活动”(例如,当它为返回创build的function)。 “内部”函数是在包含一个loopIndexvariables的范围内创build的,该variables设置为在调用IIFE时的值。 所以当你试图从内部函数中引用一个名为loopIndex的variables时,它首先检查自己的作用域(并且没有find一个loopIndex ), 然后开始向上遍历它的作用域链 – 首先,它检查它的作用域定义,它包含一个loopIndexvariables,其值被传递给console.log()

这就是一个闭包 – 一个函数可以访问定义的范围,即使范围被创build的函数已经执行完毕。

尽pipe通常使用bind来确保callback函数内部的值是您想要的值,但您也可以使用它来修改传递给绑定函数的参数。 在你的情况下,代码可能看起来像这样(我改变了一些variables的名称,所以它是更清楚发生了什么事情):

 for (var i = 0 ; i < 10 ; i++) { if (i % 2 === 0) { setTimeout(function(num) { console.log(num); }.bind(this, i), 2000); } else { console.log(i); } } 

在这种情况下,该函数具有.bind(this, i)附加到它。 this只是填充; bind的第一个参数始终是你想要在绑定函数parsing的内容。 然后,我们可以传入任何我们希望添加到绑定函数参数中的值 – 在这种情况下,我们希望将当前值(当函数绑定时)传递给函数。

您可以在MDN文档中阅读有关bind更多信息。

  setTimeout(function(i) { console.log(i); }, 2000); 

从setTimeout调用的函数不会被任何参数调用。 你需要创build一个闭包。

看看这个问题和接受的答案。

(这不是一个node.js特定的问题)