我正在使用 Symfony 3 和ReactPHP库来控制我的所有功能,我需要异步执行对同一函数(subFunction()
在代码中)的多次调用。我有 2 个项目(project1 和 project2):
项目1代码:
/**
* Loop an array of urls and call sub function.
**/
public function startFunction() {
$finalResponse = [];
$urls = ['www.google.es', 'www.github.com', 'www.bitbucket.org'];
foreach ($urls as $url) {
$res = $this->subFunction($url); // subfunction call ( **IT MAY TAKE A LONG TIME !!** )
$finalResponse[] = $res;
}
return $finalResponse;
}
/**
* Uses Factory loop to get the Promise returned by finalRequest function.
**/
private function subFunction($url) {
$loop = \React\EventLoop\Factory::create();
$classA = new Project2\ClassA();
$finalResponse = null;
// project 2 function call
$classA->finalRequest($url)->then(function($response) use(
&$finalResponse
) {
$finalResponse = $response;
})
return $finalResponse;
}
项目2代码:
classA {
/**
* Makes an React\HttpClient request (GET) to sent url and return his value inside a Promise.
**/
public function finalRequest($url) {
$generalDeferred = new Deferred();
$generalPromise = $generalDeferred->promise();
// make React\HttpClient request
$request = $client->request('GET', $url);
$request->on('response', function ($response) use($generalDeferred) {
$response->on('data', function ($response) {
$generalDeferred->resolve($response);
});
});
$request->end();
return $generalPromise;
}
}
问题是在每次subFunction($url)
调用时,程序都会停止,直到 sub Function 得到响应,但我需要异步执行此操作,因为此 subFunction 可能需要几秒钟。所以我想同时启动所有subFunction($url)
调用,并异步获取所有响应。
有可能解决这个问题吗?谢谢。
首先,一个应用程序中只能运行一个循环。其次,您必须使循环运行:https : //reactphp.org/event-loop/
您应该创建应用程序,然后注册所有服务和事件,启动循环并将其作为服务器运行。
$loop = React\EventLoop\Factory::create();
$server = stream_socket_server('tcp://127.0.0.1:8080');
stream_set_blocking($server, 0);
$loop->addReadStream($server, function ($server) use ($loop) {
[...]
});
$loop->addPeriodicTimer(5, function () {
[...]
});
$loop->run(); <---- you will not execute anything behind this point.
为什么?https://github.com/reactphp/event-loop/blob/master/src/ExtLibeventLoop.php#L196
public function run()
{
$this->running = true;
while ($this->running) { <------------------------------
$this->futureTickQueue->tick();
$flags = EVLOOP_ONCE;
if (!$this->running || !$this->futureTickQueue->isEmpty()) {
$flags |= EVLOOP_NONBLOCK;
} elseif (!$this->streamEvents && !$this->timerEvents->count()) {
break;
}
event_base_loop($this->eventBase, $flags);
}
}
对于循环的使用,我建议使用 Guzzle Async:http ://docs.guzzlephp.org/en/stable/faq.html
$finalResponse = [];
$promises = [];
$urls = ['www.google.es', 'www.github.com', 'www.bitbucket.org'];
foreach ($urls as $index => $url) {
$promise = $client->requestAsync('GET', $url);
$promise->then(function ($response) use ($index, &$finalResponse) {
$finalResponse[$index]=$response;
});
$promises[$index]=$promise;
}
foreach ($promises as $promise) {
$promise->wait();
}
return $finalResponse;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句