【问题标题】:Pattern for dealing with multiple I/O operations in Node.js在 Node.js 中处理多个 I/O 操作的模式
【发布时间】:2011-08-15 21:28:40
【问题描述】:

假设我有一个用 Node.js 编写的 CMS 应用程序,它将数据保存在 Redis 数据库中。当此应用程序创建新内容时,它应该增加 id 计数器,将新 id 添加到 ide 列表中,然后使用内容设置新哈希。我现在要做的是创建一个函数来执行此执行。这个函数(让我们称之为createArticle())将有一个回调并执行增量。执行增量后,回调函数会将其推送到 id 列表中。之后,另一个回调将创建哈希。哈希创建回调将调用作为参数传递给createArticle()的函数:

function createArticle(title, content, callback) {
    var client = redis.createClient();
    client.incr("idCounter", function(err, id) {
        if (err) return callback(err, data);
        client.lpush("articleIds", id, function (err, data) {
            if (err) return callback(err, data);
            var key = "article:"+id;
            client.hmset(key, "title", title, "content", content, callback);
        });
    });
}

我会或多或少这样使用这个函数(在这个例子中使用 Express):

app.post('/createarticle', function(req, res) {
    var title = req.body.article.title, 
        content = req.body.article.content;
    createArticle(title, content, function(err, data) {
        if (err) return res.render('error', { status: 500, message: 'Internal Server Error' });
        res.render('index', { status: 200, message: 'Article created!' });
    });
});

但是,这段代码对我来说有点麻烦。这是要走的路吗。还是有更好的方法来执行一系列 I/O 步骤?我在示例中使用了 Express 和 Redis,但答案不需要使用它们。

【问题讨论】:

    标签: javascript node.js asynchronous


    【解决方案1】:

    您可以将这些错误捕获器设为单行:

    function createArticle(title, content, callback) {
        var client = redis.createClient()
        client.incr("idCounter", function(err, id) {
            if (err) return callback(err, data)
            client.lpush("articleIds", id, function (err, data) {
                if (err) return callback(err, data)
                var key = "article:"+id
                client.hmset(key, "title", title, "content", content", callback)
            })
        })
    }
    

    您可以使用帮助程序来处理错误:

    function noError(errorCb, cb) {
        var slice = Array.prototype.slice
        return function (err) {
            var currentCb = err ? errorCb : cb
            currentCb.apply(this, slice.apply(arguments, err?0:1)
        }
    }
    
    function createArticle(title, content, cb) {
        var client = redis.createClient()
        client.incr("idCounter", noError(cb, function(id) {
            client.lpush("articleIds", id, noError(function (data) {
                var key = "article:"+id
                client.hmset(key, "title", title, "content", content", callback)
            }))
        })
    }
    

    或者类似的东西。

    【讨论】:

    • 一个很好的建议,我应该注意。我更改了我的 OP 以符合它。但是,您会说我构建逻辑的方式作为一个整体是可以接受的吗?
    • @brandizzi,是的,我想是的。如果您有更多回调级别,您可能希望将回调放在命名函数中,以便您的缩进不符合屏幕的右边框。此外,您可以使用帮助程序来捕获错误,我将在我的答案中举一个例子。但总的来说,我会说你的代码看起来不错。
    猜你喜欢
    • 2020-12-01
    • 2022-11-11
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    相关资源
    最近更新 更多