异步
- 单线程
- Event Loop
- jQuery 的 Deferred
- Promise
- Async/Await
单线程
JavaScript 之所以使用单线程,是因为它最初是为了处理网页上的交互和动态效果而设计的。而且使用单线程可以避免 DOM 渲染阻塞和冲突。
浏览器中 JS 执行和 DOM 渲染共用一个线程。
单线程的特点是:
- 顺序执行:一次只能执行一个任务。
- 阻塞式:当执行一个任务时,如果该任务需要等待某些操作完成,那么该任务会被阻塞,直到操作完成后才能继续执行。
- 非阻塞式:为了避免阻塞,单线程通常采用异步机制。
- 使用回调函数处理异步任务结果
- 可靠性高:由于单线程只有一个执行上下文,因此不需要考虑线程同步、锁等多线程编程问题
避免 DOM 渲染阻塞和冲突
- 浏览器需要渲染 DOM
- JS 可以修改 DOM 结构
- JS 执行的时候,浏览器 DOM 渲染会暂停
- 如果是多线程 JS 同时执行,可能导致 DOM 冲突
- webworker 支持多线程,但是不能访问 DOM
JS 必须是单线程,和 DOM 渲染互斥,而且 JS 的执行必须这样设计才可靠。
然后使用异步来解决单线程阻塞问题。
Event Loop
循环执行的顺序:
- 在执行栈中执行一个宏观任务。
- 遇到同步代码直接执行,遇到异步代码,区分宏任务和微任务,添加到对应的任务队列中。
- 当前宏任务执行完毕后,立即执行下面的所有微任务。(微任务中优先级高的先执行)
- 微任务全部执行完毕后,GUI 接管 DOM 渲染。
- 继续从任务队列中查找下一个宏任务。
微任务在下一轮 DOM 渲染之前执行,宏任务在 DOM 渲染之后执行。