From 571d212e70834ad0d7db9ed7f9e1a0b091dc1367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 24 Apr 2018 13:43:46 +0200 Subject: [PATCH] Simplify logic by moving static notifier work-around to static method --- src/Promise.php | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Promise.php b/src/Promise.php index ccf38917..74905358 100644 --- a/src/Promise.php +++ b/src/Promise.php @@ -228,11 +228,6 @@ private function call(callable $callback) if ($args === 0) { $callback(); } else { - // Store a reference to all progress handlers (will be cleared when settled) - // This way, we can use a static progress callback that is not bound to this promise instance. - // This helps avoiding garbage cycles if the callback creates an Exception. - $progress =& $this->progressHandlers; - $callback( function ($value = null) { $this->resolve($value); @@ -240,11 +235,7 @@ function ($value = null) { function ($reason = null) { $this->reject($reason); }, - \Closure::bind(function ($update = null) use (&$progress) { - foreach ($progress as $handler) { - $handler($update); - } - }, null) + self::notifier($this->progressHandlers) ); } } catch (\Throwable $e) { @@ -253,4 +244,28 @@ function ($reason = null) { $this->reject($e); } } + + /** + * Creates a static progress callback that is not bound to a promise instance. + * + * Moving the closure creation to a static method allows us to create a + * callback that is not bound to a promise instance. By passing its progress + * handlers by reference, we can still execute them when requested and still + * clear this reference when settling the promise. This helps avoiding + * garbage cycles if any callback creates an Exception. + * + * These assumptions are covered by the test suite, so if you ever feel like + * refactoring this, go ahead, any alternative suggestions are welcome! + * + * @param array $progressHandlers + * @return callable + */ + private static function notifier(&$progressHandlers) + { + return function ($update = null) use (&$progressHandlers) { + foreach ($progressHandlers as $handler) { + $handler($update); + } + }; + } }