@todojs/

Proxy 9 - throttleCache()

JavaScript

No description

fork
loading
main.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
// Configuramos un objeto y sus métodos tendrán una caché de medio segundo
var o = throttleCache ({
    m: function () { return 0 | Math.random() * 100; },
    n: function () { return 0 | Math.random() * 100; }
}, 500);

// Añadimos un nuevo método, que se comportará igual que los anteriores
o.z = function () { return 0 | Math.random() * 100; };

// Ejecutamos cada 100 milisegundos y 15 veces
var n = 0;
var interval = setInterval(() => {
    console.log (o.m(), o.n(), o.z());
    if (++n === 15) {
        clearInterval(interval);
    }
}, 100);

function throttleCache(obj, ms) {
    var throttling = {};
    return new Proxy(
        cacheObject(obj),
        {
            get: (object, property) => {
                if (typeof object[property] === 'function' && !throttling[property]) {
                    throttling[property] = setTimeout(() => {
                        throttling[property] = ! object[property].clearCache();
                    }, ms);
                }
                return Reflect.get(obj, property);
            }
        }
    );
}

function cacheObject(obj) {
    var cacheFunction = new Map();
    Object.keys(obj).forEach((p) => obj[p] = (typeof obj[p] === 'function' ? cache(obj[p]) : obj[p]));
    return new Proxy(obj, {
        set: (object, property, value) => {
            return Reflect.set(object, property, (typeof value === 'function' ? cache(value) : value));
        }
    });
}

function cache(fn) {
    var cacheData = new Map();
    fn = new Proxy(fn, {
        apply: function(target, thisArg, argumentsList) {
            var args = argumentsList.toString();
            if (cacheData.has(args)) {
                return cacheData.get(args);
            }
            var ret = Reflect.apply(target, thisArg, argumentsList);
            cacheData.set(args, ret);
            return ret;
        }
    });
    fn.clearCache = () => !cacheData.clear();
    return fn;
}
Native Browser JavaScript