我正在尝试用reactPHP实现类似js的承诺。但是由于某些原因,方法是同步执行的,只有在承诺解决后才会打印end_at。
代码:
function iterate() {
$deferred = new \React\Promise\Deferred();
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().
}); 发布于 2016-01-03 02:47:54
发布于 2018-11-25 07:07:05
代码中的问题是您使用的是一个阻塞函数:sleep()
这里引用了一些阻塞调用:https://github.com/reactphp/react/wiki/FAQ
但是承诺本身是异步的:它提供了在调用函数之前声明要在链中调用的函数的能力。
实际上,通过调用一个函数,您必须等到函数被执行,但是声明“那么您必须运行此函数”,您并不是真正地运行它,只要第一个调用返回。
所以
function iterate() {
global $loop;
$deferred = new \React\Promise\Deferred();
$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 = React\EventLoop\Factory::create();,大多数时候都是有道理的。
在这里,$loop->addTimer()调用立即返回,因此iterate()返回未解决的承诺,因此将立即调用方法then(),序列执行将与您的echo end at ...一起进行。
then()方法将行为附加到返回的承诺,不执行作为参数传递的函数。但首先,承诺必须得到回报,问题是睡眠不是异步睡眠,而是真正的2秒睡眠!
注意,您在javascript中没有对应的睡眠,您有setTimeout(),它的行为就像下面的$loop->addTimer()
https://stackoverflow.com/questions/32453834
复制相似问题