一道面试题window.setTimeout(() => { test1() }, 0); test2(); test1和2 谁先执行,考察js的异步机制和事件循环基础

答案: test2()先执行,然后再执行test1()。

原因:JS是单线程的,(PS: 虽然html5中提出了新的web标准,允许javascript 脚本创建多个线程,但子线程完全受主线程控制,且不得进行Dom操作,因此也并没有改变单线程的本质。)

setTimeout属于异步操作,JS引擎会把setTimeout的操作加入到JS的任务队列中去,test2()属于主线程上的同步操作,优先执行,等主线程上的同步操作都执行完毕,主线程空闲,才会去读取任务队列,再执行test1();

仅仅是知道答案是远远不够的,这里面用到的知识,也需要整理一下,越学越发现自己懂得越少。

一:js的同步和异步?

js语言的执行环境是“单线程”。所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

同步模式,即上面所说的模式,在主线程上排队执行的任务,任务按排列顺序执行,只有前一个任务执行完毕,才能执行后一个任务;

异步模式,其实就是延迟处理。不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。在和HTML交互的过程中,会需要一些IO操作(典型的就是Ajax请求,脚本文件加载),如果这些操作是同步的,就会阻塞其它操作,用户的体验就是页面失去了响应。异步是通过异步函数实现的,如setTimeout()。

二:什么是事件循环?

主线程中的所有同步任务执行完毕,再读取任务队列中的异步任务,这个过程是循环不断的。所以,整个的这种运行机制称为Event Loop(事件循环)。 

猜你喜欢

转载自blog.csdn.net/qq_33505829/article/details/86221834