const obj = { name: " jsCoder", skill: ["es6", "react", "angular"], say: function () { var that = this; for (var i = 0, len = this.skill.length; i < len; i++) { setTimeout((function() { console.log(i); console.log(that.skill[i]); })(), 0) console.log(i); } }};obj.say();这段代码在Node里执行会报错,但可以在浏览器中执行,执行结果:第二种写法:const obj = { name: " jsCoder", skill: ["es6", "react", "angular"], say: function () { var that = this; for (var i = 0, len = this.skill.length; i < len; i++) { (function () { var j = i; setTimeout((function () { console.log(j); console.log(that.skill[j]); }), 0) })() console.log(i); } }};obj.say();为什么,立即执行函数是异步任务吗?
2 回答
不负相思意
TA贡献1777条经验 获得超10个赞
你的setTimeout的写法是错的(如果我没猜错你的原意的话),setTimeout的第一个参数是一个回调函数,第二个参数是延迟执行的毫秒数。你的第一个参数虽然好像是一个函数,但你把这个函数用括号括起来,又在后面加了个括号立即去调用它,这样setTimeout的第一个参数遍被你设置成了这个函数的返回值而不是让setTimeout来帮你执行这个函数,从你写的这个函数来看,这个返回值应该是undefined
,而undefined
不是一个函数,它不是可调用的,我猜node里报的错应该是类似
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
at setTimeout (timers.js:425:11)
这样的错误吧?
正确的写法应该是:
setTimeout(function() {
// Do something here
}, someTime);
换种说法就是,你需要传给setTimeout的第一个参数是一个函数指针/引用,而不是当场调用这个函数——这样你将把函数的返回值而不是这个函数本身作为第一个参数传入。
另外,setTimeout确实是异步的,并且现在推荐用setImmediate
代替setTimeout(func, 0)
。
添加回答
举报
0/150
提交
取消