2013-05-16 32 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中,它几乎是无用的,几乎完全等同于观察者模式wikipediamsdnoodesign

PHP几乎完全是单线程的。 sleep也不例外。因此,您的整个承诺将阻止您的脚本,直到它完成。因此,看到作为内联执行的操作,您可能不会感到困扰。

摆脱这个小问题的一种可能的方法是让您的Promise从主脚本中分叉,这可以使用PCNTL功能家族。这将允许Promise代码在后台运行,而主脚本仍在继续。当Promise完成时,它会回来。

http://www.php.net/manual/en/function.pcntl-fork.php#98711处列出了实现这一点的方法。它使得积极使用pcntl_fork,它允许你分叉一个新的线程。它有缺点 - 其中最大的缺点是无法用信号发送任何信息来传递主流程。

+4

如果您想执行[协作式多任务处理](http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking),则回调地狱也会同步发生。顺便说一句,如果你有PHP 5.5,最好使用[生成器](http://www.php.net/manual/en/language.generators.php)(自2013年6月20日起),而不是承诺...哦,你可以在php中使用[pthreads extension](http://pthreads.org/)(自2012年以来)...所以这个答案是“最没用的”... – inf3rno

+0

正在搜索此信息在https:/ /github.com/reactphp/promise。什么时候脚本结束什么都没说。他们应该在其页面上添加一个链接到这篇文章 –

+0

pcntl现在也支持上下文信息:https://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler –

相关问题