From a29be318f3801bd5f9ea6e72b5a13d4a9f5e52d8 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 18 Jan 2016 11:25:00 +0100 Subject: [PATCH] Add Promise support when using cache.wrap --- .jshintrc | 1 + lib/caching.js | 18 ++++++++++++++ lib/callback_filler.js | 6 +++++ test/caching.unit.js | 56 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/.jshintrc b/.jshintrc index d2de774..7ab039b 100644 --- a/.jshintrc +++ b/.jshintrc @@ -20,6 +20,7 @@ "predef" : [ // Extra globals. "__dirname", + "Promise", "Buffer", "event", "exports", diff --git a/lib/caching.js b/lib/caching.js index f98bb3a..225386a 100644 --- a/lib/caching.js +++ b/lib/caching.js @@ -69,6 +69,17 @@ var caching = function(args) { options = {}; } + if (!cb) { + cb = Promise.defer(); + var work2 = work; + work = function(cb) { + Promise.resolve().then(work2).then(function(res) { + cb(null, res); + }) + .catch(cb); + }; + } + var hasKey = callbackFiller.has(key); callbackFiller.add(key, {cb: cb, domain: process.domain}); if (hasKey) { return; } @@ -91,6 +102,9 @@ var caching = function(args) { } if (!self._isCacheableValue(data)) { + if (typeof cb === 'object') { + return cb.resolve(data); + } return cb(); } @@ -104,6 +118,10 @@ var caching = function(args) { }); } }); + + if (typeof cb === 'object') { + return cb.promise; + } }; /** diff --git a/lib/callback_filler.js b/lib/callback_filler.js index 4914bf1..5f73f67 100644 --- a/lib/callback_filler.js +++ b/lib/callback_filler.js @@ -12,6 +12,12 @@ CallbackFiller.prototype.fill = function(key, err, data) { waiting.forEach(function(task) { var taskDomain = task.domain || domain.create(); + if (typeof task.cb === 'object') { + if (err) { + return taskDomain.bind(task.cb.reject)(err); + } + return taskDomain.bind(task.cb.resolve)(data); + } taskDomain.bind(task.cb)(err, data); }); }; diff --git a/test/caching.unit.js b/test/caching.unit.js index 227e4f9..c43ce7a 100644 --- a/test/caching.unit.js +++ b/test/caching.unit.js @@ -673,6 +673,62 @@ describe("caching", function() { }); }); }); + + describe("using native promises", function() { + beforeEach(function() { + cache = caching({ + store: 'memory', + max: 50, + ttl: 5 * 60 + }); + }); + + it("should be able to chain with simple promise", function(done) { + cache.wrap('key', function() { + return 'OK'; + }) + .then(function(res) { + assert.equal(res, 'OK'); + done(); + }); + }); + + it("should be able to chain with cache function as a promise", function(done) { + cache.wrap('key', function() { + return new Promise(function(resolve) { + resolve('OK'); + }); + }) + .then(function(res) { + assert.equal(res, 'OK'); + done(); + }); + }); + + it("should be able to catch errors in cache function as a promise", function(done) { + cache.wrap('key', function() { + return new Promise(function(resolve, reject) { + reject('NOK'); + }); + }) + .then(function() { + done(new Error('It should not call then since there is an error in the cache function!')); + }) + .catch(function() { + done(); + }); + }); + + it("should be able to chain with non-cacheable value", function(done) { + cache.wrap('key', function() { + return; + }) + .then(function(res) { + assert.equal(res, undefined); + done(); + }); + }); + }); }); describe("instantiating with no store passed in", function() {