Skip to content

Commit f2f9afb

Browse files
committed
Merge branch 'master' into develop
2 parents 1a5a926 + 249376e commit f2f9afb

File tree

9 files changed

+298
-9
lines changed

9 files changed

+298
-9
lines changed

.jshintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
"predef" : [ // Extra globals.
2222
"__dirname",
23+
"Promise",
2324
"Buffer",
2425
"event",
2526
"exports",
@@ -58,7 +59,7 @@
5859
"expr" : false, // Tolerate `ExpressionStatement` as Programs.
5960
"forin" : false, // Tolerate `for in` loops without `hasOwnProperty`.
6061
"immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
61-
"latedef" : true, // Prohibit variable use before definition.
62+
"latedef" : "nofunc", // Prohibit variable use before definition.
6263
"loopfunc" : true, // Allow functions to be defined within loops.
6364
"maxparams" : 4,
6465
"maxdepth" : 5,

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ See the [Express.js cache-manager example app](https://github.com/BryanDonovan/n
3333

3434
* [node-cache-manager-mongodb](https://github.com/v4l3r10/node-cache-manager-mongodb)
3535

36+
* [node-cache-manager-fs](https://github.com/hotelde/node-cache-manager-fs)
37+
3638
## Overview
3739

3840
First, it includes a `wrap` function that lets you wrap any function in cache.

lib/caching.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ var caching = function(args) {
4242
};
4343
}
4444

45+
function wrapPromise(key, promise, options) {
46+
return new Promise(function(resolve, reject) {
47+
self.wrap(key, function(cb) {
48+
Promise.resolve()
49+
.then(promise)
50+
.then(function(result) {
51+
cb(null, result);
52+
})
53+
.catch(cb);
54+
}, options, function(err, result) {
55+
if (err) {
56+
return reject(err);
57+
}
58+
resolve(result);
59+
});
60+
});
61+
}
62+
4563
/**
4664
* Wraps a function in cache. I.e., the first time the function is run,
4765
* its results are stored in cache so subsequent calls retrieve from cache
@@ -69,6 +87,10 @@ var caching = function(args) {
6987
options = {};
7088
}
7189

90+
if (!cb) {
91+
return wrapPromise(key, work, options);
92+
}
93+
7294
var hasKey = callbackFiller.has(key);
7395
callbackFiller.add(key, {cb: cb, domain: process.domain});
7496
if (hasKey) { return; }

lib/multi_caching.js

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,27 @@ var multiCaching = function(caches, options) {
4747
}
4848
}
4949

50+
function getFromHighestPriorityCachePromise(key, options) {
51+
return new Promise(function(resolve, reject) {
52+
getFromHighestPriorityCache(key, options, function(err, result) {
53+
if (err) {
54+
return reject(err);
55+
}
56+
resolve(result);
57+
});
58+
});
59+
}
60+
5061
function getFromHighestPriorityCache(key, options, cb) {
5162
if (typeof options === 'function') {
5263
cb = options;
5364
options = {};
5465
}
5566

67+
if (!cb) {
68+
return getFromHighestPriorityCachePromise(key, options);
69+
}
70+
5671
var i = 0;
5772
async.eachSeries(caches, function(cache, next) {
5873
var callback = function(err, result) {
@@ -72,11 +87,29 @@ var multiCaching = function(caches, options) {
7287
};
7388

7489
cache.store.get(key, options, callback);
75-
}, cb);
90+
}, function(err, result) {
91+
return cb(err, result);
92+
});
93+
}
94+
95+
function setInMultipleCachesPromise(caches, opts) {
96+
return new Promise(function(resolve, reject) {
97+
setInMultipleCaches(caches, opts, function(err, result) {
98+
if (err) {
99+
return reject(err);
100+
}
101+
resolve(result);
102+
});
103+
});
76104
}
77105

78106
function setInMultipleCaches(caches, opts, cb) {
79107
opts.options = opts.options || {};
108+
109+
if (!cb) {
110+
return setInMultipleCachesPromise(caches, opts);
111+
}
112+
80113
async.each(caches, function(cache, next) {
81114
var _isCacheableValue = getIsCacheableValueFunction(cache);
82115

@@ -85,7 +118,20 @@ var multiCaching = function(caches, options) {
85118
} else {
86119
next();
87120
}
88-
}, cb);
121+
}, function(err, result) {
122+
cb(err, result);
123+
});
124+
}
125+
126+
function getAndPassUpPromise(key) {
127+
return new Promise(function(resolve, reject) {
128+
self.getAndPassUp(key, function(err, result) {
129+
if (err) {
130+
return reject(err);
131+
}
132+
resolve(result);
133+
});
134+
});
89135
}
90136

91137
/**
@@ -96,13 +142,15 @@ var multiCaching = function(caches, options) {
96142
* @param {function} cb
97143
*/
98144
self.getAndPassUp = function(key, cb) {
145+
if (!cb) {
146+
return getAndPassUpPromise(key);
147+
}
148+
99149
getFromHighestPriorityCache(key, function(err, result, index) {
100150
if (err) {
101151
return cb(err);
102152
}
103153

104-
cb(err, result);
105-
106154
if (index) {
107155
var cachesToUpdate = caches.slice(0, index);
108156
async.each(cachesToUpdate, function(cache, next) {
@@ -113,9 +161,29 @@ var multiCaching = function(caches, options) {
113161
}
114162
});
115163
}
164+
165+
return cb(err, result);
116166
});
117167
};
118168

169+
function wrapPromise(key, promise, options) {
170+
return new Promise(function(resolve, reject) {
171+
self.wrap(key, function(cb) {
172+
Promise.resolve()
173+
.then(promise)
174+
.then(function(result) {
175+
cb(null, result);
176+
})
177+
.catch(cb);
178+
}, options, function(err, result) {
179+
if (err) {
180+
return reject(err);
181+
}
182+
resolve(result);
183+
});
184+
});
185+
}
186+
119187
/**
120188
* Wraps a function in one or more caches.
121189
* Has same API as regular caching module.
@@ -145,6 +213,10 @@ var multiCaching = function(caches, options) {
145213
};
146214
}
147215

216+
if (!cb) {
217+
return wrapPromise(key, work, options);
218+
}
219+
148220
var hasKey = callbackFiller.has(key);
149221
callbackFiller.add(key, {cb: cb, domain: process.domain});
150222
if (hasKey) { return; }
@@ -165,8 +237,6 @@ var multiCaching = function(caches, options) {
165237
.on('error', function(err) {
166238
if (callbackFiller.has(key)) {
167239
callbackFiller.fill(key, err);
168-
} else {
169-
cb(err);
170240
}
171241
})
172242
.bind(work)(function(err, data) {
@@ -211,7 +281,7 @@ var multiCaching = function(caches, options) {
211281
options: options
212282
};
213283

214-
setInMultipleCaches(caches, opts, cb);
284+
return setInMultipleCaches(caches, opts, cb);
215285
};
216286

217287
/**
@@ -230,7 +300,7 @@ var multiCaching = function(caches, options) {
230300
options = {};
231301
}
232302

233-
getFromHighestPriorityCache(key, options, cb);
303+
return getFromHighestPriorityCache(key, options, cb);
234304
};
235305

236306
/**

lib/stores/memory.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var memoryStore = function(args) {
2727
lruCache.set(key, value, maxAge);
2828
if (cb) {
2929
process.nextTick(cb);
30+
} else {
31+
return Promise.resolve(value);
3032
}
3133
};
3234

@@ -35,6 +37,7 @@ var memoryStore = function(args) {
3537
cb = options;
3638
}
3739
var value = lruCache.get(key);
40+
3841
if (cb) {
3942
process.nextTick(function() {
4043
cb(null, value);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
},
2626
"devDependencies": {
2727
"coveralls": "^2.3.0",
28+
"es6-promise": "^3.0.2",
2829
"istanbul": "^0.2.11",
2930
"jscs": "^1.9.0",
3031
"jsdoc": "^3.3.0",

test/caching.unit.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,62 @@ describe("caching", function() {
673673
});
674674
});
675675
});
676+
677+
describe("using native promises", function() {
678+
beforeEach(function() {
679+
cache = caching({
680+
store: 'memory',
681+
max: 50,
682+
ttl: 5 * 60
683+
});
684+
});
685+
686+
it("should be able to chain with simple promise", function(done) {
687+
cache.wrap('key', function() {
688+
return 'OK';
689+
})
690+
.then(function(res) {
691+
assert.equal(res, 'OK');
692+
done();
693+
});
694+
});
695+
696+
it("should be able to chain with cache function as a promise", function(done) {
697+
cache.wrap('key', function() {
698+
return new Promise(function(resolve) {
699+
resolve('OK');
700+
});
701+
})
702+
.then(function(res) {
703+
assert.equal(res, 'OK');
704+
done();
705+
});
706+
});
707+
708+
it("should be able to catch errors in cache function as a promise", function(done) {
709+
cache.wrap('key', function() {
710+
return new Promise(function(resolve, reject) {
711+
reject('NOK');
712+
});
713+
})
714+
.then(function() {
715+
done(new Error('It should not call then since there is an error in the cache function!'));
716+
})
717+
.catch(function() {
718+
done();
719+
});
720+
});
721+
722+
it("should be able to chain with non-cacheable value", function(done) {
723+
cache.wrap('key', function() {
724+
return;
725+
})
726+
.then(function(res) {
727+
assert.equal(res, undefined);
728+
done();
729+
});
730+
});
731+
});
676732
});
677733

678734
describe("instantiating with no store passed in", function() {

0 commit comments

Comments
 (0)