我试图实现js类承诺与reactPHP。但是由于某些原因,方法是同步执行的,end_at
只有在promise被解析后才会打印出来。
function iterate() {
$deferred = new ReactPromiseDeferred();
sleep(2);
$deferred->resolve();
return $deferred->promise();
}
Route::get('test/async', function() {
echo "start execution at ".time()."<br>"; // this executed first
iterate()->then(function($result) {
echo "got result result at ". time() . "<br>"; // this is second
}, function($error) {
}, function ($finally) {
});
echo "end at " . time(); // this is executed only after then().
});
承诺本身不是异步的。承诺本身只是为您提供运行一些代码的能力,然后根据成功或失败执行不同的回调,然后将这些概念链接在一起。
异步代码可以使用特定于任务的模块执行。如果您试图发出HTTP请求,可以使用ReactPHP的HTTP -client模块。如果希望异步执行系统命令,可以考虑使用子进程模块。
如果你想做一些完全不同或定制的事情,你应该把工作抽象成它自己的异步行为,类似于Predis异步库。可能使用promise模块来提供成功/失败回调。
代码中的问题是您正在使用阻塞函数:sleep()
但是promise本身是异步的:它提供了在调用链中的函数之前声明要调用的函数的能力。
实际上通过调用函数你必须等待直到函数被执行,但是声明"then you must run this",你并没有真正运行它,只要第一次调用返回。
function iterate() {
global $loop;
$deferred = new ReactPromiseDeferred();
$loop->addTimer(2, function () use ($deferred) {
$deferred->resolve();
});
return $deferred->promise();
}
Route::get('test/async', function() {
echo "start execution at ".time()."<br>"; // this executed first
iterate()->then(function($result) {
echo "got result result at ". time() . "<br>"; // this when solved
}, function($error) {
}, function ($finally) {
});
echo "end at " . time(); // this is executed only after iterate() and then() returns.
});
我想你有一个全局的$loop = ReactEventLoopFactory::create();
,大多数时候它是有意义的。
这里$loop->addTimer()
调用立即返回,因此iterate()
返回承诺,未解决,因此方法then()
被立即调用,并且顺序执行继续与您的echo end at ...
then()
方法将行为附加到返回的承诺,不执行作为参数传递的函数。但首先必须返回承诺,问题是睡眠不是异步睡眠,但它真的睡了2秒!
注意,在javascript中没有sleep对应项只有setTimeout()
,它的行为就像这样$loop->addTimer()