2013-05-16 6 views
8

Ich habe über das Promise-Muster gelesen, und ich habe versucht, eine Version in PHP mit Hilfe von ein paar Beispielen und meinem eigenen Verständnis, wie es funktionieren sollte, zu kodieren. Ist das ein vernünftiges Beispiel für das Promise-Muster, oder habe ich das falsch umgesetzt?Ist diese Implementierung ein gutes Beispiel für ein Versprechen in PHP?

class PromiseClass { 
    private $callbacks = array(); 
    private $last_return; 
    function promise($promise) { 
     if (get_class($promise) == 'Promise') { 
      return $promise; 
     } else if (is_callable($promise)) { 
      $this->then($promise); 
      return $this; 
     } 
    } 
    public function then (callable $callback) { 
     $this->callbacks[] = $callback; 
     return $this; 
    } 
    public function resolve() { 
     $callback = array_shift($this->callbacks); 
     if (is_callable($callback)) { 
      $this->last_return = $callback($this->last_return); 
     } 
     if (count($this->callbacks) > 0) { 
      $this->resolve(); 
     } 
    } 
} 

Beispiel für die Verwendung:

$promiser->promise(function() { 
     echo "sleeping\n"; 
     sleep(3); 
     return 3; 
    }) 
    ->then(function($args) { 
     echo " in second function, $args\n"; 
    }); 
$promiser->resolve(); 
+3

Dies ist besser geeignet für codereview.stackexchange.com –

+0

@ JohnConde hat Recht. Wie auch immer, um Ihre Neugier zu stillen - das ist in der Tat ein Promise-Muster in PHP! ... Außer dass 'sleep()' blockiert. Ankommende antworten. –

Antwort

12

Ihre Versprechen Umsetzung ist meist richtig. Es gibt jedoch ein Problem: zumindest in PHP ist es größtenteils nutzlos und entspricht fast vollständig dem Observer-Muster wikipediamsdnoodesign.

PHP ist fast vollständig single-threaded. sleep ist keine Ausnahme. Daher wird Ihr gesamtes Versprechen Ihr Skript blockieren, bis es abgeschlossen ist. Als Ergebnis, da die Operationen inline ausgeführt werden, können Sie auch nicht stören.

Ein möglicher Weg, um dieses kleine Problem loszuwerden, wäre, Ihre Promise aus dem Hauptskript zu verzweigen, was mit der PCNTL-Familie von Funktionen möglich ist. Dadurch kann der Promise-Code im Hintergrund ausgeführt werden, während das Hauptscript fortgesetzt wird. Wenn das Versprechen abgeschlossen ist, kommt es zurück.

Eine Möglichkeit, dies zu tun, ist unter http://www.php.net/manual/en/function.pcntl-fork.php#98711 umrissen. Es verwendet aktiv pcntl_fork, mit dem Sie einen neuen Thread forkieren können. Es hat Nachteile - die größte von ihnen ist die Unfähigkeit, den Hauptprozess durch nichts als Signale zu signalisieren.

+4

Callback-Hölle tritt auch durch Synchronisierung auf, wenn Sie [kooperatives Multitasking] (http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking) machen wollen. BTW, wenn Sie PHP 5.5 haben, ist es besser, [Generatoren] (http://www.php.net/manual/en/language.generators.php) (seit 20 Jun 2013) anstelle von Versprechungen zu verwenden ... Ohh and ofc du kannst threads in php mit der [pthreads extension] (http://pthreads.org/) haben (seit 2012) ... Also diese Antwort ist "meistens nutzlos" ... – inf3rno

+0

War auf der Suche nach dieser Information unter https://github.com/reactphp/promise. Nichts darüber, wann das Skript endet. Sie sollten einen Link zu diesem Beitrag auf ihrer Seite hinzufügen –

+0

pcntl unterstützt jetzt auch Kontextinformationen: https://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler –

Verwandte Themen