Skip to content

Latest commit

 

History

History
226 lines (205 loc) · 8.36 KB

README.md

File metadata and controls

226 lines (205 loc) · 8.36 KB

PHP Promises/A+ implementation

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

This package provides Promise/A+ PHP implementation.

Branches

Master Build Status Coverage Status

Develop Build Status Coverage Status

Installation

Console run:

    composer require streamcommon/promise

Or add into your composer.json:

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

If you want see TRUE promise then install Swoole extension. For more info visit the Swoole repo

NOTE: TRUE promise work only in CLI mode

Promise

Promise is a library which provides Promise/A+ PHP implementation.

All Promise it a special PHP classes that contains its state:

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

To initiate a new promise, you can use static method PromiseInterface::create or create with new. All resulting Promise has PromiseInterface::STATE_PENDING state.

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

When function($resolve, $reject) executor finishes the job, it should call one of the functions:

  • $resolve to indicate that the job finished successfully and set Promise state to PromiseInterface::STATE_FULFILLED
    $resolve = function ($value) {
        $this->setState(PromiseInterface::STATE_FULFILLED);
        $this->setResult($value);
    };
  • $reject to indicate that an error occurred and set Promise state to PromiseInterface::STATE_REJECTED
    $reject = function ($value) {
        $this->setState(PromiseInterface::STATE_REJECTED);
        $this->setResult($value);
    };

Method PromiseInterface::then() it be called after promise change stage. In terms of our analogy: this is the “subscription".

    public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface;
  • $onFulfilled run when the Promise is resolved and it has PromiseInterface::STATE_FULFILLED state.
  • $onFulfilled run when the Promise is rejected and it has PromiseInterface::STATE_REJECTED state.

NOTE: If $onFulfilled or $onFulfilled is not a callable function it was ignore

Calling PromiseInterface::resolve() creates a successfully executed promise with the result value.

    public static function resolve($value): PromiseInterface;

It is similar to:

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

Similarly PromiseInterface::reject() creates an already executed promise with an error value.

    public static function reject($value): PromiseInterface;

It is similar to:

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

Sub promise

When function($resolve, $reject) executor finishes the job, it can return PromiseInterface.

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

In this case, it will wait for the execution of sub promise.

Method PromiseInterface::then() can return PromiseInterface to.

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

For more info check example scripts.

Example

Standard 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

If you want see TRUE promise then install Swoole extension. For more info visit the Swoole repo

NOTE: TRUE promise work only in CLI mode

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

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

Sub async 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;
    });

If use ExtSwoolePromise with daemon|cycle|loop you must use Swoole\Runtime::wait()

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