JavaScript异步编程的干货知识点分享
作者:𝑺𝒉𝒊𝒉𝑯𝒔𝒊𝒏𝒈
前言
想象一下,如果所有的代码必须按照顺序执行,每一个函数都必须等待前面的函数执行完毕,那么这样的程序将会变得极其缓慢,也使我们无法利用计算机硬件资源的优势。
这时候,JavaScript 的异步编程模式就为我们提供了可能性。
那么,异步是什么意思?如何实现异步编程?不同的异步模式有哪些?本文将围绕这些问题展开讨论。
异步是什么
异步指的是在某个请求处理结束之前,程序可以继续执行其他的操作,而不需要等待这个请求处理结束才能继续执行后面的代码。
简单来说,异步编程就是在发送一个请求后,立刻返回一个响应,而不必等待该请求的返回结果。相比之下,同步编程则需要等待请求完成之后,才能进行下一步的操作。
举个例子:假设我们正在下载一个很大的文件,同步编程模式会让我们一直等着下载完成后再去进行下一步的操作。但异步编程就可以让我们边下边处理,减少等待时间。
如何实现异步编程?
实现异步编程的方式有很多种,其中比较常见的是回调函数、Promise 和 async/await。
回调函数
回调函数是最早出现的实现异步编程的方式之一。回调函数通常指定一个函数作为参数,并在异步操作完成后将结果传递给这个函数。
例如,我们可以通过以下方式使用回调函数来获取 api 数据:
function getData(callback) { $.get('/api/data', function(data) { callback(data); }); }
在该代码中,我们使用了 jQuery 的 $.get
方法发送请求,并在成功的时候使用传递的回调函数返回数据。当接收到数据后,回调函数被执行并把数据传递给它。
虽然回调函数是一种简单有效的方法,但它们也容易导致 回调地狱 ,因为必要的处理程序需要相互嵌套,使代码变得难以阅读和维护。
Promise
Promise 是 ES6 中引入的一种新型异步编程模式,通过链式调用 then 方法,每一步都返回一个 Promise 对象,从而避免了回调地狱的问题。
假设我们需要通过 Promise 请求 api 获取数据,代码示例如下:
function getData() { return new Promise(function(resolve, reject) { $.get('/api/data', function(data) { resolve(data); }); }); }
在这个示例中,我们定义了一个 getData
函数来获取数据,并使用 Promise 包裹了它。如果我们需要进一步处理返回的数据,可以通过链式调用 then
方法来处理。
例如:
getData().then(function(data) { console.log(data); });
尽管 Promise 已经解决了回调地狱的问题,但是它仍然有一些限制。首先,我们需要手动创建一个 Promise 对象,而且会导致代码变得冗长。其次,在较老的浏览器中,Promise 也不一定能够工作,尤其在 IE 等浏览器中兼容性并不好。
async/await
async/await是 ES8 中引入的异步编程模式,本质上也是基于 Promise 的。async 表示该函数返回一个 Promise 对象,而 await 关键词是用来等待一个 Promise 对象的结果。
在使用 async/await 编写异步代码时,我们不再需要手动创建和管理 Promise 对象,而是通过 async 关键字将其转换为异步函数。以下是一个简单的例子:
async function getData() { const data = await $.get('/api/data'); return data; }
在这个例子中,我们使用了 async/await 来等待 api 请求完成后获取数据。await $get('/api/data')
这行代码会阻塞代码执行,直到请求返回数据才会继续执行接下来的代码。
虽然 async/await 看起来更简洁,但是它仍然依赖于 Promise,并不能解决 Promise 无法兼容早期浏览器的问题。此外,如果错误处理不当,async/await 可能会使应用程序变得混乱并且难以维护。所以在使用 async/await 时一定要注意错误处理。
异步模式有哪些
除了上述常见的回调函数、Promise 和 async/await 外,还有其他一些实现异步编程的方式,例如事件监听、发布/订阅模式、流式操作等。这里我们稍微介绍一下事件监听和发布/订阅模式。
事件监听
在 JavaScript 中,我们可以使用 addEventListener 来绑定一个事件的处理程序。当事件发生时,它会自动调用相应的处理程序。
例如:
const button = document.querySelector('button'); function handleClick() { console.log('Button has been clicked'); } button.addEventListener('click', handleClick);
在这个例子中,我们通过 addEventListener 方法将 handleClick 函数添加为按钮的 click 事件的处理程序。每当按钮被点击时,handleClick 函数就会被调用。
发布/订阅模式
发布/订阅模式,也称为观察者模式,是一种常见的异步编程模式。在该模式中,订阅者可以注册对某一特定事件的监听,当该事件发生时,发布者会通知所有已注册的订阅者执行相应操作。
在 JavaScript 中,我们可以使用 EventEmitter 类来实现此模式。以下是一个简单的例子:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', () => { console.log('an event occurred!'); }); myEmitter.emit('event');
在这个例子中,我们通过创建一个 MyEmitter 类来扩展 EventEmitter,并在其上继续添加事件和监听器。当 myEmitter.emit
方法被调用时,我们的回调函数就会被执行。
结论
在 JavaScript 中,异步编程技术是高效利用计算机资源和提高代码性能的关键。了解不同的异步编程模式和实现方式对于开发人员来说非常重要。
回调函数是最早出现的实现异步编程的方式之一,然而它易导致代码的深层次嵌套,后来 Promise 通过链式调用方法让代码变得更加整洁,而 async/await 更是通过将代码转换为异步函数,简化了异步代码的编写。
除此之外,还有事件监听、发布/订阅等异步编程模式可以使用。不同的场景和需求需要采用不同的异步编程技术,排查异步回调地狱以获得更好的可读性和可维护性。
以上就是JavaScript异步编程的干货知识点分享的详细内容,更多关于JavaScript异步编程的资料请关注脚本之家其它相关文章!