定义
同步: 一个进程在执行某个请求的时候, 若该请求需要一段时间才能返回信息, 那么这个进程将会一直等待下去, 直到收到返回信息才继续执行下去
异步: 进程不需要一直等下去, 而是继续执行下面的操作, 不管其他进程的状态当有消息返回时系统会通知进程进行处理, 这样可以提高执行的效率
线程: 线程是程序中一个单一的顺序控制流程进程内一个相对独立的可调度的执行单元, 是系统独立调度和分派 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 没有机会被推入同步队列
来源: https://juejin.im/post/5aa789ff6fb9a028de446052