UnderscoreFunction::throttle()   A
last analyzed

Complexity

Conditions 4
Paths 1

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
eloc 11
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 20
rs 9.9
1
<?php
2
3
/*
4
 * This file is part of the PHP-UNDERSCORE package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc\Underscore;
13
14
class UnderscoreFunction extends UnderscoreArray
15
{
16
    /**
17
     * Returns a callable which when invoked caches the result for given arguments
18
     * and reuses that result in subsequent calls.
19
     *
20
     * @param callable $fn The main callback.
21
     *
22
     * @return mixed
23
     */
24
    public function memoize(callable $fn)
25
    {
26
        static $memo = [];
27
28
        return function () use (&$memo, $fn) {
29
            $hash = \md5(\json_encode($args = \func_get_args()));
30
31
            if (isset($memo[$hash])) {
32
                return $memo[$hash];
33
            }
34
35
            return $memo[$hash] = \call_user_func_array($fn, $args);
36
        };
37
    }
38
39
    /**
40
     * Cache the result of callback for given arguments and reuse that in subsequent call.
41
     *
42
     * @param callable $fn   The main callback.
43
     * @param int      $wait The time to wait in millisec.
44
     *
45
     * @return mixed
46
     */
47
    public function delay(callable $fn, $wait)
48
    {
49
        return function () use ($fn, $wait) {
50
            \usleep(1000 * $wait);
51
52
            return \call_user_func_array($fn, \func_get_args());
53
        };
54
    }
55
56
    /**
57
     * Returns a callable that wraps given callable which can be only invoked
58
     * at most once per given $wait threshold.
59
     *
60
     * @param callable $fn   The main callback.
61
     * @param int      $wait The callback will only be triggered at most once within this period.
62
     *
63
     * @return mixed The return set of callback if runnable else the previous cache.
64
     */
65
    public function throttle(callable $fn, $wait)
66
    {
67
        static $previous = 0;
68
        static $result   = null;
69
70
        return function () use ($fn, &$previous, &$result, &$wait) {
71
            $now = $this->now();
72
73
            if (!$previous) {
74
                $previous = $now;
75
            }
76
77
            $remaining = $wait - ($now - $previous);
78
79
            if ($remaining <= 0 || $remaining > $wait) {
80
                $previous = $now;
81
                $result   = \call_user_func_array($fn, \func_get_args());
82
            }
83
84
            return $result;
85
        };
86
    }
87
88
    /**
89
     * Returns a function that is the composition of a list of functions,
90
     * each consuming the return value of the function that follows.
91
     *
92
     * Note that last function is executed first.
93
     *
94
     * @param callable         $fn1
95
     * @param callable         $fn2
96
     * @param ...callable|null $fn3 And so on!
97
     *
98
     * @return mixed Final result value.
99
     */
100
    public function compose(callable $fn1, callable $fn2 /* , callable $fn3 = null */)
101
    {
102
        $fns   = \func_get_args();
103
        $start = \func_num_args() - 1;
104
105
        return function () use ($fns, $start) {
106
            $i      = $start;
107
            $result = \call_user_func_array($fns[$start], \func_get_args());
108
109
            while ($i--) {
110
                $result = $fns[$i]($result);
111
            }
112
113
            return $result;
114
        };
115
    }
116
}
117