在编程领域,回调在异步执行中起着至关重要的作用。虽然人们普遍认为回调是异步操作的,但这种行为背后的底层机制对于许多人来说仍然不确定。本文将深入研究在基于回调的编程中启用异步执行的语法和实现细节。
与普遍看法相反,没有特定的语法元素来指示函数是异步执行还是同步执行。回调可以在任一模式下运行,例如以下情况:
异步:
setTimeout(function(){ console.log("this is async"); }, 100);
同步:
an_array.forEach(function(x){ console.log("this is sync"); });
JavaScript 本身不具备任何异步执行函数的固有机制。要实现此行为,可以采用以下两种方法之一:
C 编码函数(如 setTimeout)依赖复杂的技术来促进异步执行。涉及的主要机制是事件循环。
每个 Web 浏览器的核心都是事件循环,它是一个残余互联网早期出现的异步网络协议。这种机制允许浏览器同时处理多个 I/O 请求,而无需求助于额外的线程。
事件循环依赖于 C 中称为 select()(或类似变体)的关键系统调用:
select (max, readlist, writelist, errlist, timeout)
select() 使系统能够同时监控大量 I/O 操作。当任何选定的 I/O 通道上的数据可用时,该函数返回,向浏览器发出信号以启动适当的回调执行。
当注册回调函数时,JavaScript 解释器会存储它并同时调用 select() 函数。返回后,解释器将回调与特定的 I/O 通道关联起来并触发其执行。
select() 还使浏览器能够通过超时来控制回调的调用时间。通过仔细调节传递给 select() 的超时参数,可以安排回调以预定的时间间隔执行。这构成了 setTimeout 和 setInterval 等函数的基础。
除了事件循环之外,Web 浏览器还使用 Web Worker 来促进 JavaScript 代码在单独线程中的异步执行。然而,这些工作线程仍然必须通过 select() 与主事件循环互连,以与主线程通信。
Node.js 与 Web 浏览器一样,利用线程进行文件/磁盘 I/O 操作。完成这些任务后,线程与 Node.js 事件循环进行通信,从而提示执行关联的回调。
异步的概念基于回调的编程中的执行不能从语法本身直接辨别。它是底层机制的结果,主要是事件循环及其与 select() 等 C 级函数的交互。事件循环使浏览器能够同时处理多个 I/O 操作,确保回调的非阻塞执行。理解这些原则对于掌握异步编程及其跨平台应用的复杂性至关重要。
以上是JavaScript 实际上是如何使回调异步的?的详细内容。更多信息请关注PHP中文网其他相关文章!