2013-05-16 19 views
8

Ho letto del pattern Promise e ho provato a codificare una versione in PHP con l'aiuto di alcuni esempi e la mia comprensione di come dovrebbe funzionare. È quello che ho trovato con un ragionevole esempio del modello Promise, o l'ho implementato in modo errato?Questa implementazione è un buon esempio di Promessa 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(); 
     } 
    } 
} 

uso Esempio:

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

Questo è più adatto per codereview.stackexchange.com –

+0

@JohnConde ha ragione. Tuttavia, per alleviare la tua curiosità - questo è davvero un modello di Promessa in PHP! ... Tranne che 'sleep()' sta bloccando. Rispondi in arrivo. –

risposta

12

L'implementazione promessa è per lo più corretta. C'è, tuttavia, un problema: che, almeno in PHP, è per lo più inutile e quasi completamente equivalente al pattern Observer wikipediamsdnoodesign.

PHP è quasi completamente single-threaded. sleep non fa eccezione. In quanto tale, l'intera Promessa bloccherà il tuo script fino a quando non sarà completo. Di conseguenza, visto che le operazioni sono eseguite in linea, potresti anche non preoccuparti.

Un possibile modo per sbarazzarsi di questo piccolo problema è quello di far sì che il Promesso biforchi dallo script principale, che è possibile utilizzando la famiglia di funzioni PCNTL. Ciò consentirà l'esecuzione del codice Promise in background, mentre lo script principale continua. Al termine della Promessa, ritorna.

Un modo per fare ciò è delineato allo http://www.php.net/manual/en/function.pcntl-fork.php#98711. Fa uso attivo di pcntl_fork, che consente di inserire un nuovo thread in una forcella. Ha degli svantaggi, il più grande dei quali è l'incapacità di inviare messaggi al processo principale con segnali diversi.

+4

L'inferno di callback si verifica anche per sincronizzazione se si desidera eseguire [multitasking cooperativo] (http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking). Se avete php 5.5 è meglio usare [generatori] (http://www.php.net/manual/en/language.generators.php) (dal 20 giugno 2013) invece di promesse ... Ohh e ofc puoi avere discussioni in php con l'estensione [pthreads] (http://pthreads.org/) (dal 2012) ... Quindi questa risposta è "per lo più inutile" ... – inf3rno

+0

Cercavo queste informazioni su https://github.com/reactphp/promise. Nulla ha detto su quando termina la sceneggiatura. Dovrebbero aggiungere un link a questo post sulla loro pagina –

+0

pcntl ora supporta anche le informazioni di contesto: https://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler –

Problemi correlati