php-promise/promise

PHP Promise

dev-master 2019-04-04 13:31 UTC

This package is not auto-updated.

Last update: 2024-09-29 06:02:31 UTC


README

PHP Promise 是一个库,它像 JavaScript Promise 一样异步处理 PHP。该库使用 pthreads,这是一个 PHP 扩展。如果您想使用此库,则需要安装 pthreads 扩展。您可能还需要在配置中使用 --enable-maincontainer-zts 选项重新编译 PHP。

另请参阅: https://github.com/krakjoe/pthreads

例如在 Dockerfile

FROM centos:7

# Setup
RUN yum -y install epel-release wget
RUN cd /tmp && wget http://jp2.php.net/get/php-7.2.7.tar.gz/from/this/mirror -O php-7.2 && tar zxvf php-7.2

# Dependencies installation
RUN yum -y install git gcc gcc-c++ make libxml2-devel libicu-devel openssl-devel

# PHP installation
RUN cd /tmp/php-7.2.7 && \
    ./configure --enable-maintainer-zts --enable-pcntl --enable-intl --enable-zip --enable-pdo --enable-sockets --with-openssl && \
    make && \
    make install

# pthreads installation
RUN yum -y install autoconf
RUN cd /tmp && git clone https://github.com/krakjoe/pthreads.git && cd pthreads && \
    phpize && \
    ./configure && \
    make && \
    make install

# Add an extension to php.ini
RUN echo extension=pthreads.so >> /usr/local/lib/php.ini

PHP Promise 结构

PHP Promise 结构如下。 Promise structure

要求

  • PHP >= 7.2
  • pthreads 3

开始使用

运行 composer require 命令。

$ composer require php-promise/promise:dev-master

接下来,运行下面的示例代码,您将开始使用 Promise。

// After 5 seconds, Promise will say a message "solved It!"
$promise = (new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    sleep(5);
    $resolve("Solved It!\n");
}))->then(function ($message) {
    echo $message;
});

您可以使用 Promise::all 等待多个 Promise 处理,然后将它们收集到 Promise 结果中。

// Say as follows:
// [RESOLVE] After 3 seconds says!
// [RESOLVE] After 5 seconds says!
// Sorry, Promise was rejected.
$promises = [];
$promises[] = (new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    sleep(5);
    $resolve("[RESOLVE] After 5 seconds!\n");
}))->then(function ($message) {
    echo $message;
});
$promises[] = (new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    sleep(3);
    $reject("[REJECT] After 3 seconds!\n");
}))->then(function ($message) {
    echo $message;
});

\Promise\Promise::all($promises)->then(function () {
    echo "Okay, Promise is glad\n";
})->catch(function () {
    echo "Sorry, Promise was rejected\n";
});

// or

\Promise\Promise::all($promises[0], $promises[1])->then(function () {
    echo "Okay, Promise is glad\n";
})->catch(function () {
    echo "Sorry, Promise was rejected\n";
});

支持的框架

  • Laravel
    • 需要使用 SafetyLoader。
  • CakePHP

用例

  • 例如,您可以使用它来运行重型处理。

提供方法

Promise::__construct( 可调用 $callee( Resolver $resolve, Rejecter $reject, ...$parameters ), ...$parameters ): Promise

  • 构造函数从您的代码中调用,并立即运行 $callee 函数。
  • $callee 有两个参数,即 $resolve$reject,它们是可调用的函数。
  • $resolve$callee 中调用,它立即在 Promise::then 中运行解析函数。
  • $reject$callee 中调用,它立即在 Promise::catch 中运行拒绝函数。
  • 您可以定义 $parameters,您想传递资源、对象和任何类型的参数到 Promise 上下文中。

例如:)

(new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    // Promise call `then` method when you called `$resolve` here.
    $resolve();
    
    // Promise call `reject` method when you called `$reject` here.
    $reject();
}))->then(function () {
    echo 'You can see this message when `$resolve` called.';
})->catch(function () {
    echo 'You can see this message when `$reject` called.';
});

例如:)

$handle = fopen('test.log', 'rw');
(new \Promise\Promise(function (Resolver $resolve, Rejecter $reject, $handle) {
    $reject($handle);
}, $handle))->then(function ($handle) {
    fwrite($handle, 'You can pass resource parameter.');
});

Promise::all( Promise ...$promises ): Promise

  • 等待多个 Promise 处理,然后将它们收集到 Promise 结果中。

Promise::race( Promise ...$promises ): Promise

  • Promise::race 当 Promise 获得成功或失败时返回一个 Promise。

Promise::then( 可调用 $onFulfilled, 可调用 $rejected ): Promise

  • Promise::catch$resolve 调用时调用。

例如:)

(new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    $resolve();
}))->then(function () {
    echo 'You can see this message when `$resolve` call.';
});

Promise::catch( 可调用 $rejected ): Promise

  • Promise::catch$reject 调用时调用。

例如:)

(new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    $reject();
}))->catch(function () {
    echo 'You can see this message when `$resolve` call.';
});

Promise::finally( 可调用 $onFinally ): Promise

  • Promise::finally$resolve$catch 调用时调用。

例如:)

(new \Promise\Promise(function (Resolver $resolve, Rejecter $reject) {
    $resolve();
}))->then(function () {
    // do something
})->catch(function () {
    // do something
})->finally(function () {
     echo 'You can see this message when `$resolve` or `$catch` called.';
});

注释

  • 由于 pthreads 在线程之间传递参数时存在问题,因此在 PHP 中,resolvereject 只能传递可序列化的值。
  • 例如,不能传递通过如 fopen 打开的流打开的 resource 值。

单元测试

PHPUnit 测试

$ composer run-script phpunit  

代码检查测试

$ composer run-script phpcs