Skip to content

Commit

Permalink
Added \nspl\f\throttled higher order function
Browse files Browse the repository at this point in the history
  • Loading branch information
ihor committed Jun 26, 2018
1 parent 10631fb commit 3c4eb5c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ $pairs = a\zip([1, 2, 3], ['a', 'b', 'c']);
* [curried](#curriedfunction-withoptionalargs--false)
* [uncurried](#uncurriedfunction)
* [memoized](#memoizedfunction)
* [throttled](#throttledfunction-wait))
* [Callbacks](#callbacks)
* [nspl\op](#nsplop)
* [Callbacks](#callbacks-1)
Expand Down Expand Up @@ -288,6 +289,28 @@ Hello world!
Hello world!
```

##### throttled($function, $wait)

Returns throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds.
```php
$f = function() {
echo "Invoked\n";
};

$throttled = throttled($f, 10);

$startedAt = microtime(true);
do {
$throttled();
} while((microtime(true) - $startedAt) * 1000 < 30); // 30ms
```
which outputs
```
Invoked
Invoked
Invoked
```

##### Callbacks

```nspl\f``` provides all these functions as callbacks in its constants which have the same names as the functions.
Expand Down
23 changes: 23 additions & 0 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ $pairs = a\zip([1, 2, 3], ['a', 'b', 'c']);
* [curried](#curriedfunction-withoptionalargs--false)
* [uncurried](#uncurriedfunction)
* [memoized](#memoizedfunction)
* [throttled](#throttledfunction-wait))
* [Callbacks](#callbacks)
* [nspl\op](#nsplop)
* [Callbacks](#callbacks-1)
Expand Down Expand Up @@ -288,6 +289,28 @@ Hello world!
Hello world!
```

##### throttled($function, $wait)

Returns throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds.
```php
$f = function() {
echo "Invoked\n";
};

$throttled = throttled($f, 10);

$startedAt = microtime(true);
do {
$throttled();
} while((microtime(true) - $startedAt) * 1000 < 30); // 30ms
```
which outputs
```
Invoked
Invoked
Invoked
```

##### Callbacks

```nspl\f``` provides all these functions as callbacks in its constants which have the same names as the functions.
Expand Down
21 changes: 21 additions & 0 deletions nspl/f.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,27 @@ function memoized(callable $function)
}
const memoized = '\nspl\f\memoized';

/**
* Returns throttled version of the passed function, that, when invoked repeatedly, will only
* actually call the original function at most once per every wait milliseconds.
*
* @param callable $function
* @param int $wait
* @return callable
*/
function throttled(callable $function, $wait)
{
return function () use ($function, $wait) {
static $invokedAt = 0;
$now = microtime(true);
if ($now - $invokedAt >= $wait / 1000) {
$invokedAt = $now;
$function();
}
};
}
const throttled = '\nspl\f\throttled';

//region deprecated
/**
* @deprecated
Expand Down
26 changes: 26 additions & 0 deletions tests/NsplTest/FTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function \nspl\f\I;
use function \nspl\f\curried;
use function \nspl\f\uncurried;
use function \nspl\f\throttled;

use const \nspl\f\apply;
use const \nspl\f\flipped;
Expand All @@ -26,6 +27,7 @@
use const \nspl\f\pipe;
use const \nspl\f\curried;
use const \nspl\f\uncurried;
use const \nspl\f\throttled;

//region deprecated
use function \nspl\f\map;
Expand Down Expand Up @@ -261,6 +263,8 @@ public function testCurried()
$f2 = $f1('b');
$f3 = $f2('c');
$this->assertEquals('abcd', $f3('d'));

$this->assertEquals('\nspl\f\curried', curried);
}

public function testUncurried()
Expand All @@ -269,6 +273,28 @@ public function testUncurried()
$strReplace = uncurried($curriedStrReplace);

$this->assertEquals('Hello world!', $strReplace('_', ' ', 'Hello_world!'));

$this->assertEquals('\nspl\f\uncurried', uncurried);
}

public function testThrottled()
{
$counter = 0;

$count = function() use (&$counter) {
++$counter;
};

$throttled = throttled($count, 10);

$startedAt = microtime(true);
do {
$throttled();
} while((microtime(true) - $startedAt) * 1000 < 100); // 100ms

$this->assertEquals(10, $counter);

$this->assertEquals('\nspl\f\throttled', throttled);
}

//region deprecated
Expand Down

0 comments on commit 3c4eb5c

Please sign in to comment.