Nodejs 中关于阻塞的疑惑

发布于 1周前 作者 nodeper 来自 nodejs/Nestjs

Nodejs 中关于阻塞的疑惑

上传使用了 formidable, 有些处理用到了 listener, 那么问题来了, 监听是异步的, 如何中断返回结果呢. 看下代码

var received = 0;
form.on('progress', function(bytesReceived, bytesExpected) {
    received += bytesReceived;
    if (received > 1024*1024) {
    	res.json({err: "图片过大"})
    	return;
    }
});

...

form.parse(req, function(err, fields, files) {
    var file = files.icon;
    res.json({url: file.path.replace('public', '')})
});

这个写法是错误的, 会报 Can't set headers after they are sent. 应该如何改进呢


7 回复

检查 http body 的大小不是应该先去检查 http 请求头的 content-length 大小么?


不太明白你为什么这样写
因为执行了 2 次 res.json
可以加个标识变量

<br>var isSended = false;<br>var received = 0;<br>form.on('progress', function(bytesReceived, bytesExpected) {<br> received += bytesReceived;<br> if (!isSended &amp;&amp; received &gt; 1024*1024) {<br> res.json({err: "图片过大"})<br> return;<br> }<br>});<br>form.parse(req, function(err, fields, files) {<br> var file = files.icon;<br> !isSended &amp;&amp; res.json({url: file.path.replace('public', '')})<br>});<br>

忘记加上更改了 0.0
res.json 后面加上 isSended = true;

对 Http 请求没搞明白, 先这么写,再慢慢改,这个不是主要的问题

你那个写法不行,没法中断程序的进行,后边是执行写文件的操作,我那样做是先判断文件大小,要阻止后边的代码

在 Node.js 中,理解阻塞(blocking)和非阻塞(non-blocking)操作对于编写高效、可扩展的应用程序至关重要。Node.js 是基于事件驱动和非阻塞 I/O 模型的,这意味着它使用异步编程来处理 I/O 操作,如文件读写、网络请求等。

阻塞与非阻塞

阻塞操作会暂停程序的执行,直到操作完成。这在传统的多线程模型中很常见,但 Node.js 采用单线程模型,通过事件循环(event loop)来处理异步操作,从而避免阻塞。

示例代码

以下是一个简单的示例,展示了 Node.js 中如何避免阻塞:

// 阻塞示例(同步读取文件)
// const fs = require('fs');
// const data = fs.readFileSync('example.txt', 'utf8');
// console.log(data);

// 非阻塞示例(异步读取文件)
const fs = require('fs');

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

console.log('文件读取操作已发起,等待异步回调...');

在上面的代码中,注释部分展示了同步(阻塞)读取文件的方式,而实际执行的是异步(非阻塞)读取文件。异步读取允许 Node.js 在等待文件读取完成的同时继续处理其他任务,如打印“文件读取操作已发起,等待异步回调…”。

总之,理解并利用 Node.js 的非阻塞特性是构建高效、响应迅速的应用的关键。通过异步编程,你可以充分利用系统资源,避免传统阻塞操作带来的性能瓶颈。

回到顶部