【问题标题】:Blocking or not blocking (Express.js)阻塞或不阻塞 (Express.js)
【发布时间】:2014-05-25 17:56:11
【问题描述】:

屏蔽还是不屏蔽,现在的问题是:

这里是简单的路由暴露,服务器存储临时图像的文件夹。该方法只返回图像,仅此而已。

 app.get('/uploads/fullsize/:file',function (req, res){
            var file = req.params.file;
            console.log("Crap comign from passport file: " + file)
            var img = fs.readFileSync(myPath  + "/uploads/fullsize/" + file);
            res.writeHead(200, {'Content-Type': 'image/jpg' });
            res.end(img, 'binary');
        } );

我关心的是下面一行:

var img = fs.readFileSync(myPath  + "/uploads/fullsize/" + file);

这似乎是同步呼叫。我应该将其更改为异步吗?

fs.readFile(req.files.file.path, function (err, imageBinaryData) {

  //read code here
 });

这是一个合理的担忧还是我反应过度了?如果我有 1000 个并发用户在做同样的事情,我会阻止说吗?

【问题讨论】:

    标签: javascript asynchronous express fs


    【解决方案1】:

    是的,您应该将其更改为异步调用。我建议使用Q library 进行此调用以及其他异步调用。

    示例(直接来自 Q 文档):

    var readFile = Q.denodeify(FS.readFile);
    

    然后这样使用它:

    readFile("foo.txt", "utf-8")
        .then(function(data) {
        //other processing
    }
    

    或者适应你的例子:

    app.get('/uploads/fullsize/:file',function (req, res){
                var readFile = Q.denodeify(FS.readFile);
                var file = req.params.file;
                console.log("Crap comign from passport file: " + file)
                readFile(myPath  + "/uploads/fullsize/" + file)
                    .then(function(img) {
                         res.writeHead(200, {'Content-Type': 'image/jpg' });
                         res.end(img, 'binary');
                     })
                    .fail(function(err) {
                         res.send(500, {message:err});
                     }
            } );
    

    【讨论】:

    • 承诺与回调。这个应用程序中有很多CB。但最后,我将不得不“升级”promise 的应用程序。
    • 您可以在对您最有意义的地方添加承诺。通常,当您看到代码“向右移动”时,表明回调地狱,您应该考虑使其基于 Promise。此外,Q(如您在此示例中所见)允许您将节点样式的回调代码转换为基于承诺的代码。此外,Q github 页面上的示例展示了如何使您的代码回调和承诺友好,我建议您尝试一下以熟悉它,然后您会更清楚什么时候“然后”化是有意义的你的代码。
    • 这里还有一个想法... Promise 通常有助于使异步代码看起来更加同步,因此您的代码将变得更具可读性,并且您还可以解决更棘手的问题,例如您遇到的情况在完成并发送响应之前等待几个异步调用完成。 Q(以及其他 Promise 库)可以极大地帮助实现这一点。
    • 是的,你说得有道理。你提到代码移动到右侧......我称之为箭头。我已经在某种程度上使用了 async.waterfall 来对抗它。但是,对于多个异步完成,我需要 Promise :)
    【解决方案2】:

    是的——我们应该尽可能地异步。

    “readFile”很好! 但这可能不是最重要的部分:

    此外,路径显示“全尺寸”,因此您应该考虑流式传输文件。 您谈到了 1000 个并发用户,这取决于图像的大小:

    异步 ​​readFile 会将整个文件加载到内存中。如果您有 1000 个用户,每个用户同时加载 >8MB 怎么办。您的服务器内存可能已“满”。

    对于“流媒体”,我可以推荐这个视频: Node.js - streaming 25GB text file

    【讨论】:

    • 好点塞巴斯蒂安。我一定会看看流媒体选项。
    猜你喜欢
    • 1970-01-01
    • 2012-02-20
    • 2016-07-06
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    相关资源
    最近更新 更多