diff --git a/LazyCollection.php b/LazyCollection.php index 2debb01..95fd218 100644 --- a/LazyCollection.php +++ b/LazyCollection.php @@ -1570,6 +1570,28 @@ public function tapEach(callable $callback) }); } + /** + * Throttle the values, releasing them at most once per the given seconds. + * + * @return static + */ + public function throttle(float $seconds) + { + return new static(function () use ($seconds) { + $microseconds = $seconds * 1_000_000; + + foreach ($this as $key => $value) { + $fetchedAt = $this->preciseNow(); + + yield $key => $value; + + $sleep = $microseconds - ($this->preciseNow() - $fetchedAt); + + $this->usleep((int) $sleep); + } + }); + } + /** * Flatten a multi-dimensional associative array with dots. * @@ -1781,4 +1803,32 @@ protected function now() ? Carbon::now()->timestamp : time(); } + + /** + * Get the precise current time. + * + * @return float + */ + protected function preciseNow() + { + return class_exists(Carbon::class) + ? Carbon::now()->getPreciseTimestamp() + : microtime(true) * 1_000_000; + } + + /** + * Sleep for the given amount of microseconds. + * + * @return void + */ + protected function usleep(int $microseconds) + { + if ($microseconds <= 0) { + return; + } + + class_exists(Sleep::class) + ? Sleep::usleep($microseconds) + : usleep($microseconds); + } }