1.如何理解同步 异步
同步(sync) 代码按照从上往下进行执行 会阻塞代码的继续执行 直到操作完成
异步(async) 指代码执行不会等待任务完成就继续执行下一个代码,允许代码在等待异步操作完成的同时继续执行 提高了程序的响应式和性能
2.主线程与异步线程
JavaScript是单线程语言 又成它为主线程 负责处理所有同步代码
单线程在同一时间只能做一件事情 只有多线程才能支持同一时间做多件事情
JavaScript实现异步线程是因为代码的运行环境 是在浏览器和node.js中 为异步执行提供了多线程支持 当在执行一个异步操作时 这个操作会先移除主线程 然后由浏览器和node.js提供的其他线程处理
3.宏任务队列 微任务队列
在JavaScript中 异步任务又分为宏任务和微任务
宏任务分为 setTimeout setInterval 事件处理函数 setImmediate(node.js环境)
微任务队列 分为 promise.then回调 promise.catch回调 mutationObserver的回调 process.nextTick(node.js环境)
宏任务队列由代码运行环境提供 微任务由语言提供 在代码执行过程中 微任务的优先级高于宏任务
4.理解任务队列
任务队列是用来存储待处理的回调函数的队列
当执行完异步API时,该API会在代码运行环境提供的其他线程中执行,执行完成后异步API对应的回调函数会推入任务队列中等待执行
当主线成中的代码执行完成后 任务队列中的回调函数才会被放入主线程中执行
任务列也分为宏任务队列和微任务队列 异步API执行完成后 对应的回调函数会被放入对应的任务队列中
事件循环的流程
事件循环机制是JavaScript实现异步的一种方法
因为JavaScript是单线程运行的 在代码执行时,通过将不同函数的执行上下文压入 执行栈中 来保证代码的有序执行
1.先执行同步任务,如果遇到异步任务,js引擎并不会一直等待其返回结果,而是将这个异步任务挂起,交给浏览器或者node.js 其他线程去处理,然后继续执行 执行栈中的其他的同步任务
2.当异步任务执行完毕后 在将异步任务对应的回调函数 加入到一个任务队列中等待执行
3.任务队列分为 宏任务队列和微任务队列 当执行栈中的事件执行完毕后 js引擎会首先判断微任务队列中是否有任务可以执行 如果有,就将微任务队首的事件压入栈中执行
4.当微队伍队列中的任务都执行完毕后 在去执行宏任务队列中的任务 因为微任务队列优先级比宏任务队列高
5.如果宏任务队列中有微任务 继续执行微任务 如此反复循环 直到任务队列为空 这就是JavaScript的事件循环机制
console.log('start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
})
console.log('script end');
// 输出顺序为:
// start
// script end
// promise1
// setTimeout