streamcommon/promise

PHP-CLI Promise 实现

1.2.5 2020-06-28 14:12 UTC

This package is auto-updated.

Last update: 2024-09-29 01:34:06 UTC


README

PHP >= 7.2 Swoole >= 4.2 Latest Stable Version Total Downloads License

本软件包提供 Promise/A+ PHP 实现。

分支

Master Build Status Coverage Status

Develop Build Status Coverage Status

安装

控制台运行

    composer require streamcommon/promise

或者在您的 composer.json 中添加

    "require": {
        "streamcommon/promise": "*"
    }

如果您想看到真正的 Promise,请安装 Swoole 扩展。更多详情请访问 Swoole 仓库

注意:TRUE promise 只在 CLI 模式下工作

Promise

Promise 是一个库,提供 Promise/A+ PHP 实现。

所有 Promise 都是一个包含其状态的特殊 PHP 类

  • pending - PromiseInterface::STATE_PENDING
  • fulfilled - PromiseInterface::STATE_FULFILLED
  • rejected - PromiseInterface::STATE_REJECTED

要启动一个新的 Promise,您可以使用静态方法 PromiseInterface::create 或使用 new 创建。所有生成的 Promise 都具有 PromiseInterface::STATE_PENDING 状态。

    $promise = new Promise(function(callable $resolve, callable $reject));
    // OR
    $promise = Promise::create(function(callable $resolve, callable $reject))

function($resolve, $reject) 执行器完成工作时,它应该调用其中一个函数

  • $resolve 以指示工作成功完成并将 Promise 状态设置为 PromiseInterface::STATE_FULFILLED
    $resolve = function ($value) {
        $this->setState(PromiseInterface::STATE_FULFILLED);
        $this->setResult($value);
    };
  • $reject 以指示发生了错误并将 Promise 状态设置为 PromiseInterface::STATE_REJECTED
    $reject = function ($value) {
        $this->setState(PromiseInterface::STATE_REJECTED);
        $this->setResult($value);
    };

方法 PromiseInterface::then() 在 Promise 改变阶段后被调用。在我们的类比中:这是“订阅”。

    public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface;
  • $onFulfilledPromise 解决并具有 PromiseInterface::STATE_FULFILLED 状态时运行。
  • $onFulfilledPromise 被拒绝并具有 PromiseInterface::STATE_REJECTED 状态时运行。

注意:如果 $onFulfilled$onRejected 不是一个可调用的函数,则会被忽略

调用 PromiseInterface::resolve() 创建一个成功执行的带有结果值的 Promise。

    public static function resolve($value): PromiseInterface;

它类似于

    $promise = new Promise(function(callable $resolve) {
        $resolve($value)
    });

类似地,PromiseInterface::reject() 创建一个已执行的带有错误值的 Promise。

    public static function reject($value): PromiseInterface;

它类似于

    $promise = new Promise(function(callable $resolve, callable $reject) {
        $reject($value)
    });

子 Promise

function($resolve, $reject) 执行器完成工作时,它可以返回 PromiseInterface

    $promise = Promise::create(function (callable $resolve) {
        $resolve(Promise::create(function (callable $subResolve) {
            $subResolve(42);
        }));
    });

在这种情况下,它将等待子 Promise 的执行。

方法 PromiseInterface::then() 可以返回 PromiseInterface

    $promise->then(function ($value) {
        return Promise::create(function (callable $resolve) use ($value) {
            $resolve($value + 1);
        });
    });

更多详情请查看 示例脚本

示例

标准 Promise

    use Streamcommon\Promise\Promise;
    
    $promise = Promise::create(function (callable $resolve) {
        $resolve(41);
    });
    $newPromise = $promise->then(function ($value) {
        return $value + 1;
    });
    $promise->then(function ($value) {
        echo $value . ' === 41' . PHP_EOL;
    });
    $newPromise->then(function ($value) {
        echo $value . ' === 42' . PHP_EOL;
    });
    $promise->wait(); // promise execution

如果您想看到真正的 Promise,请安装 Swoole 扩展。更多详情请访问 Swoole 仓库

注意:TRUE promise 只在 CLI 模式下工作

    use Streamcommon\Promise\ExtSwoolePromise;
    
    // be careful with this
    \Swoole\Runtime::enableCoroutine(); // IF YOU WANT REALY ASYNC
    
    $promise = ExtSwoolePromise::create(function (callable $resolve) {
        // the function is executed automatically when the promise is constructed
        $resolve(41);
    });
    $promise->then(function ($value) {
        // the function is executed automatically after __constructor job
        return $value + 1;
    })->then(function ($value) {
        // the function is executed automatically after ::then()
        echo $value . PHP_EOL;
    });

子 Promise

    use Streamcommon\Promise\Promise;

    $promise = Promise::create(function (callable $resolve) {
        $resolve(Promise::create(function (callable $resolve) {
            $resolve(42);
        }));
    });
    $newPromise = $promise->then(function ($value) {
        return $value + 1;
    });
    $superNewPromise = $promise->then(function ($value) {
        return Promise::create(function (callable $resolve) use ($value) {
            $resolve($value + 2);
        });
    });
    $promise->then(function ($value) {
        echo $value . ' === 42' . PHP_EOL;
    });
    $newPromise->then(function ($value) {
        echo $value . ' === 43' . PHP_EOL;
    });
    $superNewPromise->then(function ($value) {
        echo $value . ' === 44' . PHP_EOL;
    });
    $promise->wait();

子异步 Promise

    use Streamcommon\Promise\ExtSwoolePromise;
    
    // be careful with this
    \Swoole\Runtime::enableCoroutine(); // IF YOU WANT REALY ASYNC
    
    $promise = ExtSwoolePromise::create(function (callable $resolve) {
        $promise = ExtSwoolePromise::create(function (callable $resolve) {
            $resolve(41);
        });
        $promise->then(function ($value) use ($resolve) {
            $resolve($value);
        });
    });
    $promise->then(function ($value) {
        return $value + 1;
    })->then(function ($value) {
        echo $value . PHP_EOL;
    });

如果您使用 ExtSwoolePromisedaemon|cycle|loop,则必须使用 Swoole\Runtime::wait()

    \Swoole\Runtime::enableCoroutine();
    while (true) {
        ///
        Some code with ExtSwoolePromise
        ///
        \Swoole\Runtime::wait();
    }