js同步 异步 运行机制

需要知道的那些事:

1.JS是单线程的(为什么?因为能提高效率。作为浏览器脚本语言,js的主要用途是与用户互动,操作DOM。而这也就决定它只能为单线程,否则会带来很复杂的同步问题),也就是说无法同时执行好几段代码,都是从上往下一句一句的执行,前面的代码要先于后面的代码一步被执行。如:

1 var a=12;
2 var b=15;//js在运行的时候,先执行把12赋值给a的操作,再执行把15赋值给b的操作

2.同步VS异步

同步:在同一时间,你只能做一件事情,即使这件事情会花费很长时间,但依旧需要你坚守在那里直到事情处理完毕;

异步:你在做一件事情时,因为这件事情会花费很长时间,在这等待过程中你可以先去处理其他事情,等这件事轮到你的时候再过来处理她即可。

差别:在于这条流水线上各个流程的执行顺序不同。

setTimeOut(定时器)VSsetTimeInterval(间隔定时器)

在js当中最基础的异步操作就是setTimeOut()以及setTimeInterval()了。

1.setTimeOut()方法用于在指定的毫秒数后执行某些操作;

 1 //3秒后弹出“Hello”
 2 var myVar;
 3  
 4 function myFunction() {
 5     myVar = setTimeout(alertFunc, 3000);
 6 }
 7  
 8 function alertFunc() {
 9     alert("Hello!");
10 }

2.API:

1 var id = setTimeout(fn,timer);
2       //fn是执行函数
3       //timer间隔时间
4       //返回一个id值,在fn未触发之前,可以通过clearTimeout(id)清除,从而不执行fn
5       clearTimeout(id);

 3.使用clearTimeOut()方法来阻止函数的执行;

4.返回一个 ID(数字),可以将这个ID传递给 clearTimeout() 来取消执行。


1.setInterval描述的是每隔多少时间执行某操作;

2.setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数;

3.API:

        var id = setInterval(fn,timer);
    //fn是要执行的函数,
    //timer是间隔时间
    //返回一个id,用于将来某个时间用clearInterval清除间隔定时器
    clearInterval(id);

区别与联系:

1.首先从概念上来说明,setTimeout多少时间之后执行某操作,只执行一次,而setInterval每隔多少时间之后执行某操作,如果不用clearInterval清除的话,将会一直执行下去;

2.两个方法都返回一个id值,用于清除定时器,分别是clearTimeout和clearInterval;

3.再次从性能上来说,setTimeout的性能是要优于setInterval的;

4.setTimeout和setInterval都不能保证到了时间点一定会执行,如:setTimeout(fn,5000),并不能保证5s之后一定能执行fn。这得取决于当前js线程队列里面还有没有其他待处理队列,如果刚好没有的话,那么就能刚好执行,如果当前线程里面已经有了其它待处理队列正在执行,那么需要排队,等到javascript线程空闲的时候才会执行定时器;

5.setTimeout是等待循环的操作执行完成之后,才继续在间隔时间之后再把循环操作添加到javascript的线程里面,而setInterval是不等待的,它从来不管放在线程里面循环操作有没有执行完成,反正到点就会把循环操作添加到javascript线程队列里面;

6.能用setInterval实现的操作,一定能用setTimeout来实现。

任务队列:

1.是一个事件的队列或者消息的队列。

2.所有任务都是在主线程上执行,形成一个执行栈(execution context stack);

3.执行完js主线程的代码才会去看浏览器任务队列中的事件,再执行js代码中该事件对应的代码;

4.任务队列里放的是ajax这类的任务,是交给浏览器发起HTTP请求去执行的,当有了返回结果就会在任务队列中增加一个事件表示该ajax请求已经返回了结果,任务队列里的任务和js主线程是同时执行的。 不影响js是单线程的这个结论,只能说浏览器还会提供接口来供js

实现异步操作;

5.一旦执行栈中所有同步任务执行完毕,系统会自动读取“任务队列”中的看看有什么事件,那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行;

6.主线程不断重复上面的第5步(只要主线程空了,就会读取任务队列,这个过程会不断重复,这也就是js的运行机制)。

原文地址:https://www.cnblogs.com/zhengyeye/p/8980461.html