node.js直通数据缓存模式
我正在寻找一种干净的方法来为以下情况构造node.js代码。我想到了使用EventEmitter来创建一种“工作流”类型的东西。此外,我还考虑过使用其中一个异步库,但考虑得较少 问题: 正在查找一段数据node.js直通数据缓存模式,node.js,design-patterns,Node.js,Design Patterns,我正在寻找一种干净的方法来为以下情况构造node.js代码。我想到了使用EventEmitter来创建一种“工作流”类型的东西。此外,我还考虑过使用其中一个异步库,但考虑得较少 问题: 正在查找一段数据 检查缓存,如果找到,返回 检查数据库,如果找到返回(存储在缓存中) 获取实时数据并返回(存储在数据库、缓存中) 我使用下面的事件发射器快速模拟了一些东西 var util = require("util"); var events = require('events'); var CheckF
var util = require("util");
var events = require('events');
var CheckForData = function() {
events.EventEmitter.call(this);
this.checkForData = function(key) {
this.emit("checkForDataRequest", key);
}
var _checkCache = function(key) {
if (key === 'cache') {
this.emit("found", {data:'cached data'});
}
else {
console.log("not found in cache "+key);
this.emit("checkDatastore", key);
}
}
var _chechDatastore = function(key) {
if (key === 'db') {
this.emit("found", {data:'db data'});
this.emit("storeCache", key, {data:'db data'});
}
else {
console.log("not found in db "+key);
this.emit("getData", key);
}
}
var _getData = function(key) {
if (key === 'live') {
this.emit("found", {data:'live data'});
this.emit("storeData", key, {data:'live data'});
}
else {
console.log("not found in live "+key);
this.emit("notFound", key);
}
}
var _storeData = function(key, data) {
this.emit("storeDb", key, data);
this.emit("storeCache", key, data);
}
var _storeDb = function(key, data) {
console.log("storing data in db. for "+key);
console.log(data);
}
var _storeCache = function(key, data) {
console.log("storing data in cache. for "+key);
console.log(data);
}
var _found = function(data) {
return data;
}
var _notFound = function(key) {
return key;
}
this.on("checkForDataRequest", _checkCache);
this.on("checkDatastore", _chechDatastore);
this.on("getData", _getData);
this.on("found", _found);
this.on("notFound", _notFound);
this.on("storeData", _storeData);
this.on("storeDb", _storeDb);
this.on("storeCache", _storeCache);
};
util.inherits(CheckForData, events.EventEmitter);
module.exports = new CheckForData();
要测试它
var checkForData = require('./check-for-data');
checkForData.on("found", function(data) {
console.log("Found data ");
console.log(data);
});
checkForData.on("notFound", function(key) {
console.log("NOOO Found data for " + key);
});
console.log("-------");
checkForData.checkForData('cache');
console.log("-------");
checkForData.checkForData('db');
console.log("-------");
checkForData.checkForData('live');
console.log("-------");
checkForData.checkForData('other');
console.log("-------");
然后async.js,我制作了一个快速检查系列,基本上是async.detectSeries,但不是返回集合中的项,而是返回结果。见下文
var async = require('async');
function check_cache(key) {
console.log('checking cache');
return null;
}
function check_datastore(key) {
console.log('checking datastore');
return null;//{data: "db data"};
}
function check_api(options) {
console.log('calling api');
return {data: "live data"};
}
function exists(item, callback) {
callback(item());
}
async.checkSeries([check_cache, check_datastore, check_api], exists, function(result) {
// result now equals the first function that return data
console.log(result);
});
有什么建议、提示、提示吗。。。?是否有我缺少的模式或库?你认为有可能/更容易做到循序渐进、循序渐进。。。?Memoize?调用方似乎要做很多工作,还有很多额外的代码似乎没有增加多少价值。在我的模型中有这样的东西
Foo.get = function (id, cb) {
var self = this;
// check the cache first
cache.get('foo:' + id, function (err, cacheFoo) {
// if found, just return it
if (!err && cacheFoo) {
return cb(null, cacheFoo);
}
// otherwise get from db
self.findOne({id: id}, function (err, dbFoo) {
if (err || !dbFoo) {
return cb(new Error('Foo not found', 404));
// you could do get live call here
}
// and store in cache
cache.store('foo:' + id, dbFoo);
return cb(null, dbFoo);
});
});
};
然后,调用方可以始终只调用
Foo.get(id,callback)
,而不必关心如何实际检索它。如果它变得更复杂,您可以使用async
库(例如恰当命名的async
)来提高代码的可读性,但这仍然应该对调用方完全隐藏。没错,我想我是在寻找一种从数据中提取查询逻辑的方法,从实际获取数据的方式中提取查询逻辑,一种cqs模式。在我们的示例中,每个对象在每个文件中都具有相同的控制流逻辑。您将使用哪种异步方法将其包装到async.js中?