我们知道 JavaScript 语言的执行环境是“单线程”,代码是一行接着一行、一个函数接着一个函数的执行,不能跳着执行。倘若其中一个方法耗时很长,后面的代码都要等待,这种执行模式叫做“同步”。
但是等待的这段时间,CPU通常是空闲的,其实可以用来执行后面的代码的。于是就有了“异步”这种执行模式的诞生,典型的像代码执行到 ajax 请求时,并不等待返回结果,而是接着往下执行,等到 ajax 请求拿到结果后再执行回调中的代码。
js 异步编程有多种方式,本文总结了常用的几种方式:
回调函数
这是异步编程最基本的方式,如 ajax 请求
axios.get('xxx', (res) => {
console.log('执行回调函数')
})
事件监听
另外一种思路是通过事件驱动,例如可以监听 ModuleA 的某一事件,当 ModuleA 触发该事件时,就执行 ModuleB 的某一方法。原理如图所示:
用代码表示大致如下:
ModuleA.on('eventSay', ModuleB.say); // 监听 ModuleA 的 eventSay 事件,当该事件被触发时,调用 ModuleB 的 say 方法
setTimeout(() => {
ModuleA.trigger('eventSay'); // 触发 ModuleA 的 eventSay 事件
}, 1000)
优点:比较直观,有利于模块化
缺点:当众多模块之间相互监听时,将会形成复杂的关系网,程序的执行流程将变得混乱不行,代码也将难以维护。
发布/订阅
这种模式和事件监听很相似,但又做了明显的优化。模块之间不再是直接监听,而是全部通过消息中心去调度,这样模块之间就完全解耦了,代码的执行逻辑也变得清晰明了。