Mau*_*uro 4 asynchronous node.js
我现在正在用NodeJS构建我的第一个项目,但我对一项任务感到困惑我认为这是一个简单的任务,我想问题是我对这些异步方法缺乏了解,但我无法在任何地方找到答案.
我有一个简单的循环迭代数组和任何元素,根据一些规则,我会调用一个函数或另一个.现在一些操作将比其他操作更快,所以我最终可以在元素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); }
}
Run Code Online (Sandbox Code Playgroud)
因此任何偶数将以2秒延迟打印,而奇数将立即打印.无论如何运行我得到
1
3
5
7
9
<<2 seconds break>>
undefined
undefined
undefined
undefined
undefined
Run Code Online (Sandbox Code Playgroud)
看起来偶数值是"丢失".如何传递值确保函数不会丢失输入值?我错过了什么吗?
谢谢,毛罗
Jon*_*nan 12
您的setTimeout参数函数被声明为采用单个参数i.当setTimeout调用没有参数的函数时,参数设置为undefined.
这似乎会略微好一点,因为它不再影响i您最初尝试引用的外部变量...
setTimeout(function() {
console.log(i);
}, 2000)
Run Code Online (Sandbox Code Playgroud)
...但是如果你运行它,你会发现它打印105次,因为你创建的每个函数都引用相同的i变量,其值将10在循环退出条件变为true并终止时.
创建一个闭包,它保存在创建i每个setTimout参数函数的循环期间的值,这样做可以解决这个问题:
setTimeout((function(i) {
return function() {
console.log(i);
}
})(i), 2000)
Run Code Online (Sandbox Code Playgroud)
将参数重命名为我们刚刚使用的立即调用函数表达式可能有助于使事情更清晰:
setTimeout((function(loopIndex) {
return function() {
console.log(loopIndex);
}
})(i), 2000)
Run Code Online (Sandbox Code Playgroud)
我们是:
i(不是对象,因此通过值有效传递).setTimeout.这是因为:
在JavaScript中创建函数会创建一个新的作用域来保存函数的参数变量以及使用该var关键字在其中声明的任何其他变量.可以把它想象成一个具有与变量名对应的属性的不可见对象.
所有函数都包含对其定义范围的引用,作为其范围链的一部分.他们仍然可以访问此范围,即使它不再"活动"(例如,当它为返回创建它的功能时)."内部"函数是在包含loopIndex变量的范围中创建的,该变量设置i为调用IIFE时的值.因此,当您尝试引用loopIndex从内部函数内部命名的变量时,它首先检查自己的范围(并且没有找到loopIndex它)然后开始向上移动其范围链 - 首先,它检查它的定义范围,它确实含有一个loopIndex变量,它的值被传递到console.log().
这就是闭包 - 一个可以访问定义范围的函数,即使创建范围的函数已经完成执行.
| 归档时间: |
|
| 查看次数: |
1544 次 |
| 最近记录: |