0

有人可以向我解释以下行为的原因吗?

我有一个 nodejs/express 网络服务器,假设其中一条发布路由包含以下代码:

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);

更新2

最终目标是像这样做 sg :

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
4

1 回答 1

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();
});
于 2012-10-15T15:40:56.990 回答