处理大file upload时,Node.js会被阻止吗?

处理大file upload时,Node.js会被阻止吗?

由于Node.js只有一个线程,所以当做大file upload时,所有其他请求都会被阻塞?

如果是这样,我应该如何处理nodejs中的file upload?

所有的I / O操作都由Node.js在内部使用多个线程来处理; 它是单线程,基于事件和asynchronous的I / Ofunction的编程接口。

因此,您的示例的大型上传是由一个由Node.jspipe理的单独线程执行的,当该线程完成其工作时,您的callback将被放到事件循环队列中。

当您执行CPU密集型任务时,它将被阻止。 比方说,我们有一个任务compute(),它需要几乎连续运行,并执行一些CPU密集型计算。


回答主要问题“ 我应该如何处理nodejs中的file upload?
检查您的代码(或库)在服务器上保存文件的位置,是否依赖于writefile()writeFileSync()
如果是使用writefile()那么它的asynchronous; 但是,如果它是writeFileSync()它是同步版本。


更新:回应评论:

“答案”不,不会阻塞“是正确的,但解释是完全错误的。JS在一个线程和I / O在一个(相同)线程。事件循环/asynchronous处理/callback使这成为可能。需要线程。“ – 由安德烈 – 西多罗夫

没有用于文件操作的asynchronousAPI,所以Node.js为此使用了一个线程池。 你可以在libuv的代码中看到它。 您可以在lib / fs.js中查看fs.readFile的源代码,您将看到binding.read 。 每当你看到在Node的核心模块中绑定,你正在看一个C ++的门户。 这个绑定可以使用NODE_SET_METHOD(target,“read”,Read)。 如果你知道任何C,你可能会认为这是一个macros – 它本来是,但它现在是一个函数。

Read返回ASYNC_CALL ,其中一个参数被read系统调用读取 。 但是等一下,不是这个function块吗?

是的 ,但这不是故事的结尾。 libuv简介如下:

libuv文件系统操作与套接字操作不同,套接字操作使用操作系统提供的非阻塞操作,文件系统操作在内部使用阻塞函数, 但在线程池中调用这些函数,并在应用程序中通知注册了事件循环的观察者互动是必需的。

简介: Node API方法writeFile()是asynchronous的,但这并不一定意味着它在下面是非阻塞的。 正如libuv 书所指出的,套接字(networking)代码是非阻塞的,但是文件系统更复杂。 有些东西是基于事件(kqueue)的,有些则使用线程池(在这种情况下)。

考虑通过开发Node.js的C代码 ,获取更多信息:

  • Unix fs.c
  • Windows fs.c

这取决于用于完成该任务的function。 如果你正在使用asynchronous函数,那么Node.js将不会被阻塞。 但也有同步function,例如fs.readFileSync ( FileSystem Doc ),将阻止执行。

只要照顾并selectasynchronousfunction。 这样Node.js将继续运行,而缓慢的任务/等待由外部库完成。 一旦这些任务完成,事件循环将处理结果并执行您的callback。

您可以在这里阅读更多关于Event Loop的信息: 了解Node.js事件循环

这就是node.js是asynchronous的确切原因。

node.js中涉及input/输出操作的大多数(所有?)函数(其中瓶颈是除CPU或RAM之外的其他设备)操作发生在一个exception线程上,让您的node.js服务器在等待时执行其他代码。