【问题标题】:Is this implementation a fair example of a Promise in PHP? [closed]这个实现是 PHP 中 Promise 的一个很好的例子吗? [关闭]
【发布时间】:2013-11-02 22:11:09
【问题描述】:

我一直在阅读有关 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();

【问题讨论】:

  • 这个更适合codereview.stackexchange.com
  • @JohnConde 是对的。然而,为了缓解你的好奇心——这确实是 PHP 中的一个 Promise 模式! ...除了 sleep() 正在阻塞。接听来电。

标签: php promise


【解决方案1】:

您的 Promise 实现大部分是正确的。然而,有一个问题:至少在 PHP 中,它几乎没有用,几乎完全等同于观察者模式wikipediamsdnoodesign

PHP 几乎完全是单线程的。 sleep 也不例外。因此,您的整个 Promise 将阻止您的脚本,直到它完成。因此,鉴于操作是内联执行的,您不妨不必费心。

摆脱这个小问题的一种可能方法是让你的 Promise 从主脚本中派生出来,这可以使用 PCNTL 系列函数。这将允许 Promise 代码在后台运行,而主脚本继续。当 Promise 完成时,它会返回。

http://www.php.net/manual/en/function.pcntl-fork.php#98711 概述了一种方法。它积极使用pcntl_fork,它允许你创建一个新线程。它有缺点 - 其中最大的缺点是无法通过信号以外的任何方式向主进程发送消息。

【讨论】:

  • 如果你想做cooperative multitasking,同步也会发生回调地狱。顺便说一句,如果你有 php 5.5,最好使用generators(自 2013 年 6 月 20 日起)而不是承诺......哦,你可以在 php 中使用 pthreads extension(自 2012 年起)线程......所以这个答案是“几乎没用的”......
  • 正在github.com/reactphp/promise 搜索此信息。没有说脚本何时结束。他们应该在他们的页面上添加指向这篇文章的链接
  • pcntl 现在也支持上下文信息:wiki.php.net/rfc/additional-context-in-pcntl-signal-handler
  • 在这个 Web 服务时代,对不同的服务器进行 HTTP 调用是一种非常常见的用例。 curl_multi_init 是任何 PHP 标准版本中内置的功能,它允许异步 HTTP 调用。 Promise 是包装这种异步行为的一种相当优雅的方式,而这正是流行的 PHP 的 HTTP 库(如 Guzzle)正在做的事情。因此,即使仅使用标准的单线程 PHP 版本,Promises 在 PHP 中也确实具有价值用例;
  • 这个问题启发了我在没有 pcntl_fork 或线程的 PHP 中实现实际的非阻塞承诺,这些承诺在大多数共享或托管托管环境中通常不可用,用于 Web 请求。我认为 react-php 和其他替代方案似乎过于复杂的框架,所以我决定使用我自己的。事实证明,要使它有用,您所缺少的只是一个事件循环和一种启动并行进程的方法,这是我用 shell_exec 实现的(在大多数系统中都可用)。这是要点:gist.github.com/jacmkno/dc13c089c3d641a2c3d48f7cde5c377b
猜你喜欢
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 2015-01-04
  • 1970-01-01
  • 2013-07-04
  • 2016-04-25
  • 1970-01-01
相关资源
最近更新 更多