Documentation

Async

Table of Contents

Functions

await()  : T
Block waiting for the given `$promise` to be fulfilled.
delay()  : void
Delay program execution for duration given in `$seconds`.
coroutine()  : PromiseInterface<string|int, T>
Execute a Generator-based coroutine to "await" promises.
parallel()  : PromiseInterface<string|int, array<string|int, T>>
series()  : PromiseInterface<string|int, array<string|int, T>>
waterfall()  : PromiseInterface<string|int, mixed>

Functions

await()

Block waiting for the given `$promise` to be fulfilled.

await(PromiseInterface<string|int, T$promise) : T
$result = React\Async\await($promise, $loop);

This function will only return after the given $promise has settled, i.e. either fulfilled or rejected.

While the promise is pending, this function will assume control over the event loop. Internally, it will run() the default loop until the promise settles and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived promise executions when using promise-based APIs is not feasible. For long-running applications, using promise-based APIs by leveraging chained then() calls is usually preferable.

Once the promise is fulfilled, this function will return whatever the promise resolved to.

Once the promise is rejected, this will throw whatever the promise rejected with. If the promise did not reject with an Exception or Throwable, then this function will throw an UnexpectedValueException instead.

try {
    $result = React\Async\await($promise, $loop);
    // promise successfully fulfilled with $result
    echo 'Result: ' . $result;
} catch (Throwable $e) {
    // promise rejected with $e
    echo 'Error: ' . $e->getMessage();
}
Parameters
$promise : PromiseInterface<string|int, T>
Tags
template

T

throws
Exception

when the promise is rejected with an Exception

throws
Throwable

when the promise is rejected with a Throwable

throws
UnexpectedValueException

when the promise is rejected with an unexpected value (Promise API v1 or v2 only)

used-by
delay()
Return values
T

returns whatever the promise resolves to

delay()

Delay program execution for duration given in `$seconds`.

delay(float $seconds) : void
React\Async\delay($seconds);

This function will only return after the given number of $seconds have elapsed. If there are no other events attached to this loop, it will behave similar to PHP's sleep() function.

echo 'a';
React\Async\delay(1.0);
echo 'b';

// prints "a" at t=0.0s
// prints "b" at t=1.0s

Unlike PHP's sleep() function, this function may not necessarily halt execution of the entire process thread. Instead, it allows the event loop to run any other events attached to the same loop until the delay returns:

echo 'a';
Loop::addTimer(1.0, function () {
    echo 'b';
});
React\Async\delay(3.0);
echo 'c';

// prints "a" at t=0.0s
// prints "b" at t=1.0s
// prints "c" at t=3.0s

This behavior is especially useful if you want to delay the program execution of a particular routine, such as when building a simple polling or retry mechanism:

try {
    something();
} catch (Throwable $e) {
    // in case of error, retry after a short delay
    React\Async\delay(1.0);
    something();
}

Because this function only returns after some time has passed, it can be considered blocking from the perspective of the calling code. While the delay is running, this function will assume control over the event loop. Internally, it will run() the default loop until the delay returns and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived promise executions when using promise-based APIs is not feasible. For long-running applications, using promise-based APIs by leveraging chained then() calls is usually preferable.

Internally, the $seconds argument will be used as a timer for the loop so that it keeps running until this timer triggers. This implies that if you pass a really small (or negative) value, it will still start a timer and will thus trigger at the earliest possible time in the future.

Parameters
$seconds : float
Tags
uses
await()

coroutine()

Execute a Generator-based coroutine to "await" promises.

coroutine(callable(A1, A2, A3, A4, A5): Array $function, mixed ...$args) : PromiseInterface<string|int, T>
React\Async\coroutine(function () {
    $browser = new React\Http\Browser();

    try {
        $response = yield $browser->get('https://example.com/');
        assert($response instanceof Psr\Http\Message\ResponseInterface);
        echo $response->getBody();
    } catch (Exception $e) {
        echo 'Error: ' . $e->getMessage() . PHP_EOL;
    }
});

Using Generator-based coroutines is an alternative to directly using the underlying promise APIs. For many use cases, this makes using promise-based APIs much simpler, as it resembles a synchronous code flow more closely. The above example performs the equivalent of directly using the promise APIs:

$browser = new React\Http\Browser();

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
    echo $response->getBody();
}, function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

The yield keyword can be used to "await" a promise resolution. Internally, it will turn the entire given $function into a Generator. This allows the execution to be interrupted and resumed at the same place when the promise is fulfilled. The yield statement returns whatever the promise is fulfilled with. If the promise is rejected, it will throw an Exception or Throwable.

The coroutine() function will always return a Proimise which will be fulfilled with whatever your $function returns. Likewise, it will return a promise that will be rejected if you throw an Exception or Throwable from your $function. This allows you easily create Promise-based functions:

$promise = React\Async\coroutine(function () {
    $browser = new React\Http\Browser();
    $urls = [
        'https://example.com/alice',
        'https://example.com/bob'
    ];

    $bytes = 0;
    foreach ($urls as $url) {
        $response = yield $browser->get($url);
        assert($response instanceof Psr\Http\Message\ResponseInterface);
        $bytes += $response->getBody()->getSize();
    }
    return $bytes;
});

$promise->then(function (int $bytes) {
    echo 'Total size: ' . $bytes . PHP_EOL;
}, function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

The previous example uses a yield statement inside a loop to highlight how this vastly simplifies consuming asynchronous operations. At the same time, this naive example does not leverage concurrent execution, as it will essentially "await" between each operation. In order to take advantage of concurrent execution within the given $function, you can "await" multiple promises by using a single yield together with Promise-based primitives like this:

$promise = React\Async\coroutine(function () {
    $browser = new React\Http\Browser();
    $urls = [
        'https://example.com/alice',
        'https://example.com/bob'
    ];

    $promises = [];
    foreach ($urls as $url) {
        $promises[] = $browser->get($url);
    }

    try {
        $responses = yield React\Promise\all($promises);
    } catch (Exception $e) {
        foreach ($promises as $promise) {
            $promise->cancel();
        }
        throw $e;
    }

    $bytes = 0;
    foreach ($responses as $response) {
        assert($response instanceof Psr\Http\Message\ResponseInterface);
        $bytes += $response->getBody()->getSize();
    }
    return $bytes;
});

$promise->then(function (int $bytes) {
    echo 'Total size: ' . $bytes . PHP_EOL;
}, function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
Parameters
$function : callable(A1, A2, A3, A4, A5): Array
$args : mixed

Optional list of additional arguments that will be passed to the given $function as is

Tags
template

T

template

TYield

template

A1 (any number of function arguments, see https://github.com/phpstan/phpstan/issues/8214)

template

A2

template

A3

template

A4

template

A5

since
3.0.0
Return values
PromiseInterface<string|int, T>

parallel()

parallel(iterable<string|int, callable(): Array> $tasks) : PromiseInterface<string|int, array<string|int, T>>
Parameters
$tasks : iterable<string|int, callable(): Array>
Tags
template

T

Return values
PromiseInterface<string|int, array<string|int, T>>

series()

series(iterable<string|int, callable(): Array> $tasks) : PromiseInterface<string|int, array<string|int, T>>
Parameters
$tasks : iterable<string|int, callable(): Array>
Tags
template

T

Return values
PromiseInterface<string|int, array<string|int, T>>

waterfall()

waterfall(iterable<string|int, callable(): Array> $tasks) : PromiseInterface<string|int, mixed>
Parameters
$tasks : iterable<string|int, callable(): Array>
Tags
template

T

Return values
PromiseInterface<string|int, mixed>

        
On this page

Search results