2013-05-16 8 views
8

私はPromiseパターンについて読んできました。PHPのバージョンアップにはいくつかの例があり、どのように動作するかを自分で理解しています。私はPromiseパターンの妥当な例を思いついたのですか、これを間違って実装しましたか?この実装はPHPのPromiseの公正な例ですか?

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(); 
     } 
    } 
} 

使用例:

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

これはcodereview.stackexchange.comの方が適しています。 –

+0

@ JohnCondeが正しいです。しかし、あなたの好奇心を和らげるために、これは確かにPHPのPromiseパターンです! ... 'sleep()'がブロックされていることを除いて。着信に応答します。 –

答えて

12

あなたの約束の実装は、主に正しいです。しかし、少なくともPHPではObserverパターンとほぼ完全に等価であり、ほとんど完全に等価であることが問題です。wikipediamsdnoodesign

PHPはほぼ完全にシングルスレッドです。 sleepも例外ではありません。そのため、プロミス全体が完了するまでスクリプトがブロックされます。結果として、操作がインラインで実行されるのを見ると、気にする必要はありません。

この小さな問題を取り除く方法は、PCNTLファミリの関数を使用してPromiseをメインスクリプトからフォークさせることです。これにより、Promiseコードはバックグラウンドで実行され、メインスクリプトは続行されます。約束が完了すると、それが戻ってくる。

これを行う方法は、http://www.php.net/manual/en/function.pcntl-fork.php#98711で概要を説明しています。 pcntl_forkを有効に使用して、新しいスレッドをforkすることができます。それには欠点があります。その中で最大のものは、シグナル以外のものによってメインプロセスにメッセージを送ることができないことです。

+4

[協調マルチタスキング](http://ja.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking)をしたい場合は、コールバック地獄も同期によって発生します。 Btwもしphp 5.5をお持ちなら、約束の代わりに[generators](http://www.php.net/manual/en/language.generators.php)(2013年6月20日以降)を使用する方が良いです... Ohh and ofcあなたは[pthreads extension](http://pthreads.org/)でphpのスレッドを持つことができます(2012年以降)...この回答は "ほとんど役に立たない" ... – inf3rno

+0

https:///github.com/reactphp/promise。スクリプトが終了したときは何も言わなかった。彼らは自分のページにこの投稿へのリンクを追加する必要があります –

+0

pcntlはコンテキスト情報もサポートします:https://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler –

関連する問題