由于js是单线程非阻塞的语言,js在代码执行的任何时候都只有一个主线程处理任务
1,执行栈和任务队列
执行栈(stack)
当我们调用一个方法时,js会生成与这个方法对应的执行环境(context)执行上下文。执行环境中存在着方法的作用域,参数,上级作用域,作用域中定义的变量以及this对象等。由于js是单线程的,一次只能执行一个方法,因此,这些方法就排队在一个单独的地方 就是执行栈(stack)
任务队列(task queue)
以上是同步代码执行的时候,当异步代码执行的时候呢,由于js非阻塞的特点,js在执行栈中遇到一个异步操作,不会一直等着异步操作返回结果,而是将它挂起(pending),接着执行其他操作,当这个异步操作返回结果之后,js会把这个事件加入与执行栈不同的另一个队列,就是任务队列
被放入事件队列中不会立即执行回调,而是要等执行栈中的操作都执行完成,主线程处于闲置状态的时候,主线程会去查找事件队列中的任务,如果有回调,那么主线程就会把事件队列中的第一位拿到执行栈中,如此就形成了事件循环(Event Loop)
微任务和宏任务
异步任务的执行优先级也会有不同,不同的异步任务分为两类,微任务(micro task) 和宏任务(macro task)
宏任务 例如 setTimeOut() setInterval()
微任务 new Promise()
上面提到,异步执行的结果会放到事件队列中,根据任务的类型分为微任务队列和宏任务队列,当执行栈中的同步任务执行完成之后,会先执行事件队列中的微任务队列,再执行宏任务队列
这就是js的事件循环机制
关于js 执行的上下文 context