PHPackages                             choval/async - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. choval/async

AbandonedArchivedLibrary[Utility &amp; Helpers](/categories/utility)

choval/async
============

A set of functions to help coding in async

v0.7.1(3y ago)157.5k12MITPHPPHP ^7.2|^8.0|^8.1

Since Sep 13Pushed 3y ago2 watchersCompare

[ Source](https://github.com/choval/async)[ Packagist](https://packagist.org/packages/choval/async)[ RSS](/packages/choval-async/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (10)Dependencies (6)Versions (52)Used By (2)

[![tests](https://github.com/choval/async/actions/workflows/tests.yml/badge.svg)](https://github.com/choval/async/actions/workflows/tests.yml)

Choval\\Async
=============

[](#chovalasync)

A library to ease handling promises in [ReactPHP](https://reactphp.org).

- [Install](#install)
- [Usage](#usage)
- [License](#license)
- Functions
    - [async](#async) Run blocking code in async mode
    - [execute](#execute) Execute a command
    - [is\_done](#is_done) Instantly return if the Promise is resolved or rejected
    - [resolve](#resolve) Use yield with promises!
    - [retry](#retry) Retry a function multiple times
    - [silent](#silent) Silently resolve
    - [sleep](#sleep) Non-blocking sleep
    - [timeout](#timeout) Adds a timeout to a Promise
    - [timer](#timer) Allows to time a Promise
    - [wait](#wait) Make async code synchronous
    - [wait\_memory](#wait_memory) Waits for a number of RAM bytes to be available
    - [PHP file functions](#file_functions) PHP's blocking file functions in async mode

Install
-------

[](#install)

```
composer require choval/async
```

Requirements
------------

[](#requirements)

- PHP 8.0+
- for `async` &amp; `execute`:
    - ext-pcntl
    - ext-posix
    - ext-sockets

Usage
-----

[](#usage)

Having the following function

```
function future($i=0)
{
    return new React\Promise\FulfilledPromise($i+1);
}
```

The ugly way:

```
future()
    ->then(function ($i) {
        return future($i);
    })
    ->then(function ($i) {
        return future($i);
    })
    ->then(function ($i) {
        return future($i);
    })
    ->then(function ($i) {
        return future($i);
    })
    ->then(function ($i) {
        echo $i;
    });

// Prints 5, but that chain nightmare...
```

Using `yield`, remember `future()` is returning a `Promise`.
And we're not blocking other events in the loop ;-)

```
Async\resolve(function () {
    $i = yield future();
    $i = yield future($i);
    $i = yield future($i);
    $i = yield future($i);
    $i = yield future($i);
    echo $i;
});

// Prints 5 as well ;-)
```

Or in a while-loop

```
Async\resolve(function () {
    $i = 0;
    while($iaddTimer(1, function () use ($defer) {
    $defer->resolve(true);
});
$promise = $defer->promise();
$i = 0;
function future($i=0)
{
    return new React\Promise\FulfilledPromise($i+1);
}
while(!Async\is_done($promise)) {
    $i++;
}
echo "Promise finished with $i loops\n";
```

### resolve

[](#resolve)

This is what will let you `yield` promises, it's like Node.js [`await`](https://github.com/caolan/async).

```
$promise = Async\resolve(function () {
    yield 1;
    yield 2;
    return 'Wazza';
});
// $promise resolves with Wazza
```

Take for example the following async events.

```
$defer1 = new React\Promise\Deferred();
$loop->addTimer(1, function () use ($defer1) {
    $defer1->resolve('hello');
});
$defer2 = new React\Promise\Deferred();
$loop->addTimer(0.5, function () use ($defer2) {
    $defer2->resolve('world');
});

$promise = Async\resolve(function () use ($defer1, $defer2) {
    $out = [];
    $out[] = yield $defer1->promise();
    $out[] = yield $defer2->promise();
    return implode(' ', $out);
});
```

`$promise` resolves with `hello world` in 1 sec, despite the second promise resolving first.

What if you need to run multiple async simultaneously?

```
$promise = Async\resolve(function () {
    $fetch = [
        'bing' =>
            Async\execute('curl https://bing.com/'),
        'duckduckgo' =>
            Async\execute('curl https://duckduckgo.com/'),
        'google' =>
            Async\execute('curl https://google.com/'),
    ];
    $sources = yield React\Promise\all($fetch);
    return $sources;
});
```

#### Memory usage

[](#memory-usage)

### silent

[](#silent)

Similar to `resolve`, but will catch any `Exception` and save it in the second parameter.
If it fails, the promise will resolve with null.

```
$fn = function () {
    throw new \Exception('hey!');
};
$promise = Async\silent($fn, $e);
// Promise resolves with null
// $e will hold an the hey! exception
```

### execute

[](#execute)

Executes a command asynchronously.
Returns a `Promise` with the output of the command.

```
Async\execute('echo "Wazza"')
    ->then(function ($output) {
        // $output contains Wazza\n
    })
    ->otherwise(function ($e) {
        // Throws an Exception if the execution fails
        // ie: 127 if the command does not exist
        $exitCode = $e->getCode();
    });
```

A `timeout` parameter (in seconds) can be passed.

### sleep

[](#sleep)

An asynchronous `sleep` function. This won't block other events.

```
$promise = Async\resolve(function () {
    $start = time();
    yield Async\sleep(2);
    $end = time();
    return $end-$start;
});
// $promise resolves in ~2 seconds
```

Remember this is a non-blocking `sleep`, if you do not wait for it or yield inside an Async\\resolve, the `Promise` will solve in the background.

```
$start = time();
Async\sleep(2);
$end = time();
// $start and $end will be the same
```

### wait

[](#wait)

Also knowsn as `sync`, makes asynchronous code blocking. Use this when you need to use an async library in a sync/blocking scenario.

This function receives one of the following: `Generator`, `Closure` or `PromiseInterface`.

```
$start = time();
Async\wait(Async\sleep(2));
$end = time();
// $end == $start+2;
```

A second float parameter is a timeout in seconds, defaults to no timeout.

A third float parameter is the interval at which to check, defaults to 0.01 secs. A low interval will consume much more CPU.

### async

[](#async)

Have a piece of blocking code that you need to run in async? Use this, just keep in mind it is using `pcntl_fork`.

First parameter is a callable, second parameter is an array of parameters for the callable.

```
$blocking_code = function ($secs) {
    sleep($secs);
    return time();
}

$secs = 1;
$promises = [];
$promises[] = Async\async($blocking_code, [$secs]);
$promises[] = Async\async($blocking_code, [$secs]);
$promises[] = Async\async($blocking_code, [$secs]);
$promises[] = Async\async($blocking_code, [$secs]);
$base = time()+$secs;

$times = Async\wait(React\Promise\all($promises));
foreach ($times as $time) {
    // $time === $base
}
```

There's a limit of 50 simultaneously running async forks. This limit can be changed by calling `Async\set_forks_limit`.
This limit is counted for `Async\execute` as well.

```
Async\set_forks_limit(100);
echo Async\get_forks_limit(); // 100
```

When the limit is reached, the code will wait for any previous fork to finish before continuing, keeping a max of async forks at the set forks limit.

### retry

[](#retry)

Runs a **function** (Closure/Generator) up to `retries` times for a "good" return. Otherwise, returns the last Exception.
This function can also ignore a set of Exception classes or messages.

```
$times = 5;
$func = function () use (&$times) {
    if(--$times) {
        throw new \Exception('bad error');
    }
    return 'ok';
};
$retries = 6;
Async\retry($func, $retries, 0.1, 'bad error')
    ->then(function ($res) {
        // $res is 'ok'
    });
```

```
/**
 * @param callable $func
 * @param int $retries=10 (optional)
 * @param float $frequency=0.001 (optional)
 * @param string $ignoress (optional) The Throwable class to catch or string to match against Exception->getMessage()
 *
 * @return Promise
 */
```

### timeout

[](#timeout)

Similar to `React\Promise\Timer\timeout()`, but allows a `Generator` or `Closure` too.

```
$func = function () {
    yield Async\sleep(2);
    return true;
};
Async\wait(Async\timeout($func, 1.5));
// Throws an Exception due to the timeout 1.5 < 2
```

### timer

[](#timer)

Saves the number of elapsed microseconds (float).

```
Async\wait(function () {

    Async\timer(function () {
        Async\sleep(0.1);
    }, $msecs);
    print_r($msecs); // ~100ms

});
```

### wait\_memory

[](#wait_memory)

Waits for a number of memory bytes to be available.
This is used inside loops to avoid memory exhaution due to multiple Promises being created and left in background.

```
Async\wait(function () {

    $loop = 20000;
    $mem = 1024*1024*16; // 16MB
    while($loop--) {
        yield Async\waitMemory($mem);
        Async\sleep(1);
    }

});
```

A second parameter can be passed for the frequency to run the check.
Returns the number of bytes remaining (`memory_limit` - `memory_get_usage()`).

### rglob

[](#rglob)

A recursive `glob` with an ignore parameter.

Consider the following files:

```
/files/
/files/a.txt
/files/b.txt
/files/a.php
/files/b.php
/files/c.php
/files/1/a.txt
/files/1/a.php
/files/1/b.php
/files/1/c.php
/files/2/a.php
/files/2/b.php
/files/2/c.php

```

```
$files = Async\wait(Async\rglob('/files/*.php', 'a'));
/*
$files has:
/files/b.php
/files/c.php
/files/1/b.php
/files/1/c.php
/files/2/b.php
/files/2/c.php
*/
```

### PHP file functions

[](#php-file-functions)

The following functions are available with the same parameters as their PHP versions, but run using `Async\async` and take an optional `LoopInterface` as their first parameter.

These are not production tested/optimized. Please use with caution.

```
file_get_contents
file_put_contents
file_exists
is_file
is_dir
is_link
sha1_file
md5_file
mime_content_type
realpath
fileatime
filectime
filemtime
file
filesize
copy
rename
unlink
touch
mkdir
rmdir
scandir
glob

```

Example:

```
$lines = Async\wait(Async\file('/etc/hosts'));
var_dump($lines);
```

License
-------

[](#license)

MIT, see LICENSE.

###  Health Score

36

—

LowBetter than 81% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Recently: every ~35 days

Total

51

Last Release

1440d ago

PHP version history (3 changes)v0.3.17PHP ^7.2

v0.5.28PHP ^7.2|^8.0

v0.7.0PHP ^7.2|^8.0|^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/f7e751254e7e7b319464bd6b51c51d9d2c5fedb4c2305ceaa580f9116cbc6a11?d=identicon)[choval](/maintainers/choval)

---

Top Contributors

[![choval](https://avatars.githubusercontent.com/u/794926?v=4)](https://github.com/choval "choval (192 commits)")

---

Tags

asyncasync-forksawaitawait-promiseschain-resolvecoroutinefilesgeneratorphppromisepromisesreactphpresolvewaityield

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/choval-async/health.svg)

```
[![Health](https://phpackages.com/badges/choval-async/health.svg)](https://phpackages.com/packages/choval-async)
```

###  Alternatives

[friendsofphp/php-cs-fixer

A tool to automatically fix PHP code style

13.5k234.7M20.6k](/packages/friendsofphp-php-cs-fixer)[react/react

ReactPHP: Event-driven, non-blocking I/O with PHP.

9.1k3.6M63](/packages/react-react)[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k379.4k24](/packages/team-reflex-discord-php)[wyrihaximus/react-child-process-messenger

Messenger decorator for react/child-process

32279.4k4](/packages/wyrihaximus-react-child-process-messenger)[clue/docker-react

Async, event-driven access to the Docker Engine API, built on top of ReactPHP.

113154.9k1](/packages/clue-docker-react)[internal/dload

Downloads binaries.

98142.7k10](/packages/internal-dload)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
