-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuncjs.js
76 lines (68 loc) · 2.39 KB
/
funcjs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
(function(u) {
/**
* Returns a function that uses the getter function to get the data for a given key,
* and if data does not exist, uses the creator function for creating data.
* Prevents the simultaneous execution of a function for the given key.
* Other callers waiting for the result.
* @param {function} getter function(key, function(error, data))
* @param {function} creator function(key, function(error))
* @param {function} hash function(key, function(error))
* @returns {function}
*/
u.getOrCreate = function(getter, creator, hash) {
var _queue = {};
function _w(thiz, successFunc, errorFunc, args) {
return function(error) {
if (error) errorFunc.call(thiz, error);
else successFunc.apply(thiz, args);
};
}
return function(key) {
var self = this;
if (hash) key = hash.apply(this, Array.prototype.slice.call(arguments, 0, arguments - 1));
var args = Array.prototype.slice.call(arguments);
var cb = arguments[arguments.length - 1];
if (key in _queue) {
_queue[key].push(_w(self, getter, cb, args));
} else {
var args2 = args.slice(0, arguments.length - 1);
getter.apply(self, args2.concat([function(error) {
if (error) {
if (key in _queue) {
_queue[key].push(_w(self, getter, cb, args));
} else {
_queue[key] = [_w(self, getter, cb, args)];
creator.apply(self, args2.concat([function(error) {
var funcs = _queue[key];
delete _queue[key];
funcs.forEach(function(f) { f(error); });
}]));
}
} else {
cb.apply(this, arguments);
}
}]));
}
};
};
/**
* Create cached version of the given func.
* @param {Function} func
* @returns {Function} cached func
*/
u.cache = function(func) {
var _c = {};
return u.getOrCreate(function(key, cb) {
cb(null, _c[key]);
}, function(key, cb) {
func(key, function(error, data) {
if (error) {
cb(error);
} else {
_c[key] = data;
cb();
}
});
});
};
})(exports);