为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这两种setTimeout执行顺序不一样

为什么这两种setTimeout执行顺序不一样

慕尼黑5688855 2019-03-17 16:14:21
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)


查看完整回答
反对 回复 2019-03-23
  • 2 回答
  • 0 关注
  • 998 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信