1

I need to return from a function call once a React/Promise has been resolved. The basic idea is to fake a synchronous call from an ansynchronous one. This means that the outer function must return a value once a promise has been resolved or rejected.

This is to create a driver for RedBeanPHP using React/Mysql. I am aware that this will likely lead to CPU starvation in the React event loop.

My initial idea was to use a generator then call yield inside a \React\Promise\Deferred::then callback.

function synchronous()
{
    $result = asynchronous();
}

function asynchronous()
{
    $deferred = new \React\Promise\Deferred;

    $sleep = function() use ($deferred)
    {
        sleep(5);
        $deferred->resolve(true);
    };

    $deferred->then(function($ret) {
        yield $ret;
    });

    $sleep();
}

The PHP generator class, AFAICT, is only directly constructable by the PHP engine itself. The then callback would need to directly invoke send on the generator of the asynchronous function for this to work.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Phillip Whelan
  • 1,697
  • 2
  • 17
  • 28

2 Answers2

1

PHP lacks both continuations as well as generator delegation, which would make it possible to call yield from inside a nested callback, making this entirely impossible to achieve for the moment.

Phillip Whelan
  • 1,697
  • 2
  • 17
  • 28
  • 1
    PHP supports yield delegation, you just have to implement it. See for example https://github.com/nikic/ditaio/blob/master/lib/stackedCoroutine.php#L26. No idea if that helps you as I don't understand the question in the least :/ – NikiC Feb 08 '14 at 10:42
  • I tried to clarify the question a bit, hope it helps. In essence I want to be able to yield a promise from a function (turning it into a generator), then invoke yield when a callback (registered inside the generator) has been called. As a note to myself here is the patch that removed the stubs for yield delegation: http://permalink.gmane.org/gmane.comp.php.cvs.general/59072. – Phillip Whelan Feb 08 '14 at 10:57
0

ReactPhp offers the async tools package which has an await function. Code can then become:

function synchronous()
{
    $result = \React\Async\await(asynchronous());
}

function asynchronous()
{
    $deferred = new \React\Promise\Deferred;

    $sleep = function() use ($deferred)
    {
        sleep(5);
        $deferred->resolve(true);
    };

    $sleep();

    return $deferred->promise();
}

George
  • 2,860
  • 18
  • 31