定义
- 同步: 一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去
- 异步: 进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率
- 线程: 线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位。指运行中的程序的调度单位
- 单线程: 单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。单线程就是进程里只有一个线程
问题
console.log(100)
setTimeout(function () {
console.log(200)
}, 0)
console.log(300)
输出:
// 100
// 300
// 200
解析
JS为单线程, 但是任务执行分为同步任务和异步任务
代码中console.log为同步任务, setTimeout为异步任务(这些基础东西就不过多解释了)
为了方便理解,我们可以认为JS这条单线程中有两条事件队列, 一条为同步队列(主事件大循环 Event Loop),一条为异步队列,同步任务在同步队列中依次执行,异步任务在异步队列中依次执行,并且这两个队列是同时执行的。但是,JavaScript引擎只会执行同步队列中的任务,那么异步队列中的任务什么时候执行呢?
JavaScript引擎会不断遍历同步队列,当同步队列为空时,会将异步队列中执行完毕的异步事件的回调函数放入同步队列执行。
回顾
现在让我们回来看看上面的面试题就很容易理解了,同步队列中console.log(100)和console.log(300)执行后,console.log(200)被推入同步队列执行,所以结果依次为100-> 300->200
PS: setTimeout(fun, 0)中的0不是立即执行的意思, 而是同步队列为空时立即将fun推入同步队列
额外
var flag = 1
setTimeout(function(){
flag = 0
}, 0)
while(flag){
console.log('running')
}
结果是什么?
答案为死循环,因为while(flag)中的代码将一直在同步队列中执行,而flag = 0没有机会被推入同步队列
作者:addone
链接:https://juejin.im/post/5aa789ff6fb9a028de446052
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。