JavaScript的异步执行的运行机制,使用setTimeout来做的例子。 首先写一小段代码: setTimeout( function () { console.log(1); } , 1000); setTimeout( function () { console.log(2); } , 800); setTimeout( function () { console.log(3); } , 600); 明白异步执行的,相信大家都知道打印的顺序吧
具体来说,异步执行的运行机制如下:
根据每个函数的设置的时间,第三个函数最先进入任务队列,第二个函数第二,第一个函数最后进入。所以弹出3 2 1.
但是又有一种情况:
setTimeout( console.log(1) , 1000); setTimeout( console.log(2) , 800); setTimeout( console.log(3) , 600);
这里涉及到另外一个问题:回调函数 "任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。 所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。 console.log(1) ,console.log(2),console.log(3)并不是构成回调函数,所以它们根本没有进入任务队列:而是按照正常的顺序在执行栈中被执行了。
第二种情况是我在讲的时候,下面一位听讲的同学在自己电脑控制台执行出来的。当时问题没有的到解决,后来我再去搜了一些资料。后面一次分享会,把自认为准确的答案给大家讲了,一位问题就这么解决了。没想到又有一个问题抛出来,把console.log(1) ,console.log(2),console.log(3)各自都加上引号就可以像第一个情况那样运行。
这时的我又蒙了,分享会完之后我就马上去查了资料,可是做了无用功,并没有找到答案,后来在看一本JavaScript的书时,找到了答案。就是标题所说的双重求值。
JavaScript像其他其他语言一样,允许在程序中提取一个包含代码的字符串,然后动态执行。有四种表中方法可以实现:eval()、Function()构造函数、setTimeout()和setInterval() var num=1,num2; //eval()执行代码字符串 sum = eval("num1 + num2"); //Function()构造函数执行代码字符串 sum=Function("num1","num2","return num1 +num 2"); //setTimeout()执行代码字符串 setTimeout("sum=num1 +num2",100); //setInterval()执行代码字符串
现在问题终于都解决了 (责任编辑:好模板) |