您的位置:首页 > Web前端 > JavaScript

JavaScript的异步执行的运行机制和setTimeout的双重求值

2016-01-15 13:04 656 查看
小生现在还是一名大三学生,本专业是工程管理,因为喜欢前端,从大二开始自学,大二上中期加入学院一个前端工作室。工作室从大三开始每周会有一次技术的分享(大三的会讲讲深一点的JavaScript和css知识,大二会把自己平时学习的体会心得拿出来讲),有一次我在讲到JavaScript的异步执行的运行机制,使用setTimeout来做的例子。

首先写一小段代码:

setTimeout( function () { console.log(1); } , 1000);

setTimeout( function () { console.log(2); } , 800);

setTimeout( function () { console.log(3); } , 600);

明白异步执行的,相信大家都知道打印的顺序吧



具体来说,异步执行的运行机制如下:


(1)所有同步任务都在主线程上执行,形成一个执行栈。

(2)主线程之外,还存在一个"任务队列"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。





根据每个函数的设置的时间,第三个函数最先进入任务队列,第二个函数第二,第一个函数最后进入。所以弹出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()执行代码字符串

现在问题终于都解决了~~这以前都是些知识点类随笔,这是我第一次写学习总结类的随笔。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: