UNPKG

3.06 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = memoize;
7
8var _setImmediate = require('./internal/setImmediate');
9
10var _setImmediate2 = _interopRequireDefault(_setImmediate);
11
12var _initialParams = require('./internal/initialParams');
13
14var _initialParams2 = _interopRequireDefault(_initialParams);
15
16var _wrapAsync = require('./internal/wrapAsync');
17
18var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
19
20function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
22/**
23 * Caches the results of an async function. When creating a hash to store
24 * function results against, the callback is omitted from the hash and an
25 * optional hash function can be used.
26 *
27 * **Note: if the async function errs, the result will not be cached and
28 * subsequent calls will call the wrapped function.**
29 *
30 * If no hash function is specified, the first argument is used as a hash key,
31 * which may work reasonably if it is a string or a data type that converts to a
32 * distinct string. Note that objects and arrays will not behave reasonably.
33 * Neither will cases where the other arguments are significant. In such cases,
34 * specify your own hash function.
35 *
36 * The cache of results is exposed as the `memo` property of the function
37 * returned by `memoize`.
38 *
39 * @name memoize
40 * @static
41 * @memberOf module:Utils
42 * @method
43 * @category Util
44 * @param {AsyncFunction} fn - The async function to proxy and cache results from.
45 * @param {Function} hasher - An optional function for generating a custom hash
46 * for storing results. It has all the arguments applied to it apart from the
47 * callback, and must be synchronous.
48 * @returns {AsyncFunction} a memoized version of `fn`
49 * @example
50 *
51 * var slow_fn = function(name, callback) {
52 * // do something
53 * callback(null, result);
54 * };
55 * var fn = async.memoize(slow_fn);
56 *
57 * // fn can now be used as if it were slow_fn
58 * fn('some name', function() {
59 * // callback
60 * });
61 */
62function memoize(fn, hasher = v => v) {
63 var memo = Object.create(null);
64 var queues = Object.create(null);
65 var _fn = (0, _wrapAsync2.default)(fn);
66 var memoized = (0, _initialParams2.default)((args, callback) => {
67 var key = hasher(...args);
68 if (key in memo) {
69 (0, _setImmediate2.default)(() => callback(null, ...memo[key]));
70 } else if (key in queues) {
71 queues[key].push(callback);
72 } else {
73 queues[key] = [callback];
74 _fn(...args, (err, ...resultArgs) => {
75 // #1465 don't memoize if an error occurred
76 if (!err) {
77 memo[key] = resultArgs;
78 }
79 var q = queues[key];
80 delete queues[key];
81 for (var i = 0, l = q.length; i < l; i++) {
82 q[i](err, ...resultArgs);
83 }
84 });
85 }
86 });
87 memoized.memo = memo;
88 memoized.unmemoized = fn;
89 return memoized;
90}
91module.exports = exports['default'];
\No newline at end of file