V8 has support for ES6 Promises and they make a clean JS-side API. So why not create promises from PHP, (later on) being resolved by PHP?
V8Js doesn’t allow direct creation of JS objects from PHP-code, a little JS-side helper needs to be used. One possibility is this:
class V8PromiseFactory
{
private $v8;
public function __construct(V8Js $v8)
{
$this->v8 = $v8;
}
public function __invoke($executor)
{
$trampoline = $this->v8->executeString(
'(function(executor) { return new Promise(executor); })');
return $trampoline($executor);
}
}
… it can be used to construct an API method that returns a Promise like this:
$v8 = new V8Js();
$promiseFactory = new V8PromiseFactory($v8);
$v8->theApiCall = function() use ($promiseFactory) {
return $promiseFactory(function($resolve, $reject) {
// do something (maybe async) here, finally call $resolve or $reject
$resolve(42);
});
};
$v8->executeString("
const p = PHP.theApiCall();
p.then(function(result) {
var_dump(result);
});
");
this code
initializes V8, V8Js and the
V8PromiseFactory
firstthen attaches an API call named
theApiCall
, that uses$promiseFactory
and passes it an executor that immediately resolves to the integer 42.then executes some JavaScript code that uses the
theApiCall
function and attaches athen
function that simply echos the value (42)
V8PromiseFactory::__invoke
should cache $trampoline
if it is used to create a lot of promises.
This code requires V8Js with pull request #219 applied to function properly.