2011-08-14 52 views
0

假設我有一個用Node.js編寫的CMS應用程序,該應用程序將數據保存在Redis數據庫上。當這個應用程序創建一個新的內容時,它應該增加id計數器,將新的id添加到ide列表中,然後用內容設置一個新的hash。我現在要做的是創建一個函數來執行這個執行。這個函數(讓我們稱之爲createArticle())將有一個回調,並執行增量。一旦增量被執行,回調函數會將其推入ID列表中。之後,另一個回調會創建哈希。哈希生成回調將調用作爲參數傳遞的功能createArticle()用於處理Node.js中的多個I/O操作的模式

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

我會用這個功能或多或少這樣(在本例中使用快遞):

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,但答案不需要使用它們。

回答

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

或類似的東西。

+0

一個很好的建議,我應該注意。我改變了我的OP以符合它。但是,你會說我的邏輯結構是可以接受的嗎? – brandizzi

+0

@brandizzi,是的,我認爲是。如果您有更多的回調級別,您可能希望將回調放入命名函數中,以便縮進不符合屏幕的右側邊界。此外,你可以使用助手來捕捉錯誤,我會在我的答案中舉一個例子。但總的來說,我會說你的代碼看起來不錯。 – thejh