Javascript-线程池和Web API在处理异步行为方面有什么区别?

bnlyeluc  于 2023-01-19  发布在  Java
关注(0)|答案(1)|浏览(115)

动机

对于Javascript和node.js,我试图理解线程池和Web API之间的区别。

我目前了解的内容

  • 线程池:多线程平台,其中每个线程执行它们自己的操作。
  • Web API:浏览器内置的API。它是事件循环的一部分,与调用堆栈和回调队列沿着启用Javascript中的异步操作。

我困惑的是
似乎线程池和API都使Javascript能够处理异步行为。
当Javascript执行单线程调用堆栈之外的代码时,它是否被发送到Web API,后者 * 使用 * 线程池为每个异步操作创建一个线程?
如果没有,那么Web API和线程池如何协同工作以给予Javascript异步功能?

c0vxltue

c0vxltue1#

"先做几件事"
我们不太清楚"Web API"是什么意思,没有内置的nodejs,nodejs中有很多不同的库,每个库都有自己的API(定时器、网络、http请求、加密、磁盘I/O等)。
如果你指的是TCP网络或者http网络,那么我可以解释几件事。
首先,nodejs使用了一个名为libuv的跨平台库,它负责nodejs环境和对操作系统的本地代码调用之间的大部分接口,包括文件I/O、定时器、磁盘I/O、网络等。
驱动大部分nodejs的事件循环在libuv中。
其次,线程池是用于某些阻塞操作的本地线程池,nodejs希望能够向Javascript提供异步接口。如果接口直接从Javascript转到阻塞本地代码实现,则该操作将阻塞,并将阻塞事件循环。因此,要使接口异步,在线程池中运行的本机代码操作的示例有磁盘I/O和一些耗时的加密操作。
然后,通过使用非阻塞操作系统API来完成网络连接,因此不需要使用本机线程或线程池。

    • 您的具体问题**

似乎线程池和WebAPI都使Javascript能够处理异步行为。
本机操作系统(如网络、文件I/O等)的接口设计与事件循环相结合,实现了异步行为。
当Javascript执行单线程调用堆栈之外的代码时,是否将其发送到Web API,后者使用线程池为每个异步操作创建一个线程?
同样,我们也不清楚术语"WebAPI"的含义,nodejs并没有为了异步执行而向其发送内容。
如果没有,那么Web API和线程池如何协同工作以提供Javascript异步功能?
将术语"WebAPI"转换为"nodejsAPI",让我们来看看这样一个操作是如何工作的。
让我们看一下fs.open(),一个打开文件的函数,当你调用fs.open()时,它会进入nodejs内置的Javascript库,检查参数,如果参数错误,则处理任何即时错误,并最终调用绑定函数,该绑定函数将来自Javascript的参数打包成本机代码可以处理的内容,然后调用本机代码函数。这些参数包括对传入fs.open()的回调的引用。
这个原生代码函数将参数转换成C/C ++可以使用的形式,从线程池中获取一个线程,然后在该线程中运行一个OS调用来打开所需的文件。然后立即返回到fs.open()的Javascript部分,fs.open()的Javascript部分然后返回到您的Javascript,并且您的Javascript继续运行任何连续的Javascript代码行,直到它最终将控制返回到事件循环。
同时文件打开操作正在另一个操作系统线程中运行。当它完成时,它将事件插入相应的事件队列(事件循环的一部分),并将它正在使用的线程返回到线程池。插入到事件队列中的此事件包括对最初传递到fs.open()的回调函数的引用以及与fs.open()的结果关联的任何数据(其中包括错误或文件句柄)。
稍后,当控制返回到事件循环时,它将看到文件I/O的事件队列有一个挂起的事件,它将从事件队列中获取该事件,并调用与该事件关联的完成回调,将与该事件关联的数据传递给它。此时,您的Javascript回调将运行,您将在该回调中获得fs.open()调用的结果。
这是nodejs中的异步操作。现在,请记住,不是每个异步操作都使用线程池。例如,计时器不使用线程。事实上,它们甚至不使用操作系统级计时器,因为事件循环有自己的计时器实现。网络也不使用线程池。

相关问题