解决方法
因此,您的示例的大上传由Node.js管理的单独的线程执行,当该线程完成其工作时,您的回调将被放置到事件循环队列中.
当您执行cpu密集型任务时,它会阻塞.假设我们有一个需要几乎连续运行的compute()任务,并进行一些cpu密集的计算.
回答主要问题“我应该如何处理nodejs中的文件上传?”检查您在服务器上保存文件的代码(或库),它是否依赖于writefile()或writeFileSync()?如果使用writefile()
,那么它的异步;但如果是writeFileSync()
它是同步版本.
更新:响应评论:
“the answer “No,it won’t block” is correct but explanation is
completely wrong. JS is in one thread AND I/O is in one (same)
thread. Event loop / asynchronous processing / callbacks make this possible. No multiple threads required. ” – by 07002
没有用于文件操作的async API,因此Node.js使用线程池.您可以在libuv的代码中看到它.您可以在lib/fs.js中查看fs.readFile的源代码,您将看到binding.read.无论何时在Node的核心模块中看到绑定,您都将看到C的入口.此绑定使用NODE_SET_METHOD(target,“read”,Read)可用.如果你知道任何C,你可能会认为这是一个宏 – 它是原来的,但它现在是一个功能.
在Read中回到ASYNC_CALL,其中一个参数是读:syscall读取.但是等等,这个功能是不是阻塞了?
是的,但这不是故事的结尾. Introduction to libuv表示如下:
“libuv文件系统操作与套接字操作不同,Socket操作使用操作系统提供的非阻塞操作,文件系统操作在内部使用阻塞功能,但在线程池中调用这些函数,并在应用程序时通知事件循环注册的观察者需要互动.“
概要:
节点API方法writeFile()
是异步的,但这并不一定意味着它在下面是非阻塞的.正如libuv book指出的那样,套接字(网络)代码是非阻塞的,但是文件系统更复杂.有些事情是基于事件的(kqueue),其他的则使用线程池(在这种情况下).
有关详细信息,请参阅C code on which Node.js is developed: