如何防止 Node.js 代码阻塞
Node.js是一个跨平台的 JavaScript 运行时环境,有助于执行和实现服务器端程序。Node 通过使用单线程事件循环机制来防止代码阻塞。在本文中,我们将讨论这个事件循环以及它是如何通过使用回调函数来实现异步函数的。
阻塞和非阻塞操作: 阻塞操作是指阻止其他代码执行直到它们完成的代码片段。而非阻塞操作允许其他代码继续执行而无需等待,并在完成时使用回调函数。
因此,阻塞代码可以说是同步工作,而非阻塞代码则是异步工作。在讨论非阻塞代码时,我们会遇到一个叫做回调的术语。回调是一个在进程完成执行并希望继续正常执行外部函数时被调用的函数。
Node 和事件循环: 现在我们知道了阻塞和非阻塞操作是什么,我们可以讨论 Node 如何防止代码阻塞。Node 使用单线程,这意味着一次只能执行一个任务。这是通过使用堆栈来实现的。在从上到下阅读代码的过程中,每个指令都被推送到堆栈中,并在执行完成后从堆栈中弹出。现在我们可能会遇到一个需要较长时间来执行的指令/函数,这可能导致堆栈弹出和后续语句执行的延迟。
所以 Node.js 允许使用 事件循环 。每当遇到这种情况时,导致延迟的进程会从堆栈中卸载,并且在主代码进一步执行的同时,该进程的执行会并行进行。因此,该函数的回调被推送到一个任务队列中,代码继续异步执行。当进程完成执行时,回调函数返回该进程的期望输出并恢复正常执行。
示例: 让我们考虑一个示例,用于演示事件循环的工作原理。
index.js
使用以下命令运行 index.js 文件。
输出:
说明: 尽管记录“Geeks”的指令在记录“For”的指令之前,但它们在控制台中被记录的顺序并非如此。发生的情况是当调用setTimeout函数时,触发了等待3秒的计时器。但是,在函数处于调用栈中时,此超时不会发生,而是由Node API处理。因此,进一步的指令会按照应有的方式进行处理,当计时器归零时,回调函数将被调用,并返回函数的结果。
引用: https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/