有人可以向我解释以下行为的原因吗?
我有一个nodejs / express webserver,让我们说其中一个帖子路由包含以下代码:
req.on('data', function() { console.log('data arrived'); })
此代码按预期工作,并在调用时将“数据到达”消息写入控制台。但是以下代码:
setTimeout(function() { req.on('data', function() { console.log('data arrived'); }) }, 1000);
尽管情况相同,也不会打印任何内容。如果我们在短时间内订阅他们的事件,请求对象流会发生什么?
我之所以需要这个,是因为我想将大文件上传到我的服务器。当邮件请求到达时,我需要创建一个数据库条目并将数据传输到其中。我无法将数据块存储在内存中,因为它们具有潜在的大小,但我不能从数据库回调中获取请求对象的数据 - 或者也不能从任何回调中获取数据块。
您是否知道如何解决此问题? 提前谢谢!
更新
以下代码仍无效:
req.pause();
setTimeout(function() {
req.on('data', function(data) { console.log('data arrived'); })
req.resume();
}, 1000);
UPDATE2
最终目标是这样做:
req.pause();
doSometingAsync(function(result) {
req.on('data', function(data) { doSomethingWithData(data, result) });
req.resume();
});
,但这似乎不起作用......
更新3
这导致单个“已过去”而没有任何其他内容:
req.pause()
setTimeout () ->
console.log 'elapsed'
req.on 'error', (error) -> console.log error
req.on 'data', (data) -> console.log 'in data'
req.on 'end', () -> console.log 'end'
req.resume()
, 2000
答案 0 :(得分:1)
答案:
您可以在数据到达时触发req.pause();
,处理数据,例如将其写入文件,当文件写入回调触发时,您可以req.resume();
来接收下一个包。
除非您使用req.once
代替req.on
这会将带宽限制在您的物理硬盘速度上,会使您的应用保持同步并降低内存使用率。
更新1答案:
这是一些伪代码:
req.on("data", function (data) {
req.pause();
/* do something with data like the following: */
some_method(some_value, data, function (success) {
if (success) {
req.resume();
}
});
});
或类似的东西:
req.on("data", function (data) {
req.pause();
console.log("data arrived");
setTimeout(function(){req.resume();}, 1000);
});
更新2答案: 你应该使用回调
在这种情况下,doSomethingWithData();
的第三个参数在此功能完成后立即触发req.resume();
。
除此之外,您应该像这样调用回调以保持异步:
var doSomethingAsync = function (data, result, cb) {
/* do something with data and result */
process.nextTick(function () {
cb();
});
};
req.pause();
doSomethingAsync(function (result) {
req.on('data', function (data) {
req.pause();
doSomethingWithData(data, result, function () {
req.resume();
});
});
req.resume();
});
或者你这样做:
var doSomethingAsync = function (data, result, req) {
/* do something with data and result */
process.nextTick(function () {
req.resume();
});
};
req.pause();
doSomethingAsync(function (result) {
req.on('data', function (data) {
req.pause();
doSomethingWithData(data, result, req);
});
req.resume();
});