Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added promise support #50

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .lint
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ predef+ setTimeout, clearTimeout

./test/index.js
./test/ext/max-age.js
predef+ setTimeout
predef+ setTimeout, Promise, global
./test/ext/promise.js
predef+ Promise, setTimeout, global

./benchmark
sub
Expand Down
2 changes: 1 addition & 1 deletion ext/dispose.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var callable = require('es5-ext/object/valid-callable')
extensions.dispose = function (dispose, conf, options) {
var del;
callable(dispose);
if (options.async && extensions.async) {
if ((options.async && extensions.async) || (options.promise && extensions.promise)) {
conf.on('deleteasync', del = function (id, result) {
apply.call(dispose, null, slice.call(result.args, 1));
});
Expand Down
50 changes: 50 additions & 0 deletions ext/promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Support for functions returning promise

'use strict';

var nextTick = require('next-tick')

, create = Object.create;

require('../lib/registered-extensions').promise = function (tbi, conf) {
var cache = create(null);

// After not from cache call
conf.on('set', function (id, __, promise) {
promise.then(function () {
// nextTick avoids error interception
nextTick(function () {
cache[id] = promise;
conf.emit('setasync', id, 1);
});
}, function () {
nextTick(function () {
conf.delete(id);
});
});
});

// From cache (sync)
conf.on('get', function (id, args, context) {
conf.emit('getasync', id, args, context);
});

// On delete
conf.on('delete', function (id) {
var result;
// If false, we don't have value yet, so we assume that intention is not
// to memoize this call. After value is obtained we don't cache it but
// gracefully pass to callback
if (!cache[id]) return;
result = cache[id];
delete cache[id];
conf.emit('deleteasync', id, result);
});

// On clear
conf.on('clear', function () {
var oldCache = cache;
cache = create(null);
conf.emit('clearasync', oldCache);
});
};
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module.exports = function (fn/*, options*/) {

// Assure extensions
if (options.async) require('./ext/async');
if (options.promise) require('./ext/promise');
if (options.dispose) require('./ext/dispose');
if (options.maxAge) require('./ext/max-age');
if (options.max) require('./ext/max');
Expand Down
6 changes: 3 additions & 3 deletions lib/configure-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module.exports = function (original, length, options) {
throw customError("Circular invocation", 'CIRCULAR_INVOCATION');
}
cache[id] = result;
if (setListeners) conf.emit('set', id);
if (setListeners) conf.emit('set', id, null, result);
return result;
}, memLength);
} else if (length === 0) {
Expand All @@ -65,7 +65,7 @@ module.exports = function (original, length, options) {
throw customError("Circular invocation", 'CIRCULAR_INVOCATION');
}
cache.data = result;
if (setListeners) conf.emit('set', 'data');
if (setListeners) conf.emit('set', 'data', null, result);
return result;
};
} else {
Expand All @@ -83,7 +83,7 @@ module.exports = function (original, length, options) {
throw customError("Circular invocation", 'CIRCULAR_INVOCATION');
}
cache[id] = result;
if (setListeners) conf.emit('set', id);
if (setListeners) conf.emit('set', id, null, result);
return result;
};
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"timers-ext": "0.1"
},
"devDependencies": {
"plain-promise": "^0.1.1",
"tad": "~0.2.3",
"xlint": "~0.2.2",
"xlint-jslint-medikoo": "~0.1.4"
Expand Down
57 changes: 56 additions & 1 deletion test/ext/max-age.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

var memoize = require('../..')
, nextTick = require('next-tick');
, nextTick = require('next-tick')
, Promise = global.Promise || require('plain-promise');

require('../../ext/async');

Expand Down Expand Up @@ -52,6 +53,60 @@ module.exports = function () {
}, 90);
}, 20);
},
Promise: function (a, d) {
var mfn, fn, i = 0;
fn = function (x, y) {
return new Promise(function (res) {
++i;
res(x + y);
});
};

mfn = memoize(fn, { promise: true, maxAge: 100 });

mfn(3, 7).then(function (res) {
a(res, 10, "Result #1");
});
mfn(5, 8).then(function (res) {
a(res, 13, "Result #2");
});
mfn(3, 7).then(function (res) {
a(res, 10, "Result #3");
});
mfn(3, 7).then(function (res) {
a(res, 10, "Result #4");
});
mfn(5, 8).then(function (res) {
a(res, 13, "Result #5");
});

setTimeout(function () {
a(i, 2, "Called #2");

mfn(3, 7).then(function (res) {
a(res, 10, "Again: Result #1");
});
mfn(5, 8).then(function (res) {
a(res, 13, "Again: Result #2");
});

setTimeout(function () {
a(i, 2, "Again Called #2");

mfn(3, 7).then(function (res) {
a(res, 10, "Again: Result #1");
});
mfn(5, 8).then(function (res) {
a(res, 13, "Again: Result #2");
});

nextTick(function () {
a(i, 4, "Call After clear");
d();
});
}, 100);
}, 20);
},
Async: function (a, d) {
var mfn, fn, u = {}, i = 0;
fn = function (x, y, cb) {
Expand Down
Loading