无法让ReactPHP承诺异步执行



我有一个PHP脚本,它将从多个RESTAPI下载的数据处理为标准化格式,并构建这些数据的数组或表。脚本当前同步执行所有内容,因此耗时过长。

我一直在努力学习如何同时或异步执行获取和处理数据的函数,这样总时间就是最慢调用的时间。从我的研究来看,ReactPHP或Amp似乎是正确的工具。

然而,我一直未能成功创建实际正确执行的测试代码。附上一个简单的例子,mysquare((代表我更复杂的函数。由于网上没有确切的例子来说明我想要实现的目标,我不得不使用一种暴力方法,在我的代码中列出了3个例子。

Q1:我是否使用了适合这份工作的工具?

Q2:你能修改我的示例代码以异步执行吗?

注意:我是一个真正的初学者,所以最简单的代码示例和最低限度的高级编程语言将不胜感激。

<?php
require_once("../vendor/autoload.php");
for ($i = 0; $i <= 4; $i++) {
// Experiment 1
$deferred[$i] = new ReactPromiseDeferred(function () use ($i) {
echo $x."n";
usleep(rand(0, 3000000));  // Simulates long network call
return array($x=> $x * $x);
});
// Experiment 2
$promise[$i]=$deferred[$i]->promise(function () use ($i) {
echo $x."n";
usleep(rand(0, 3000000));  // Simulates long network call
return array($x=> $x * $x);
});
// Experiment 3
$functioncall[$i] = function () use ($i) {
echo $x."n";
usleep(rand(0, 3000000));  // Simulates long network call
return array($x=> $x * $x);
};
}
$promises = ReactPromiseall($deferred); // Doesn't work
$promises = ReactPromiseall($promise); // Doesn't work
$promises = ReactPromiseall($functioncall); // Doesn't work
// print_r($promises);  // Doesn't return array of results but a complex object
//  This is what I would like to execute simulatenously with a variety of inputs
function mysquare($x)
{
echo $x."n";
usleep(rand(0, 3000000));  // Simulates long network call
return array($x=> $x * $x);
}
异步并不意味着多个线程并行执行。2个函数只能真正在"同一时间"运行,前提是它们(例如(执行IO(如HTTP请求(。

usleep((块,所以您一无所获。ReactPHP和Amp本身都有某种"睡眠"函数,该函数直接构建在事件循环中。

出于同样的原因,不能只能使用curl,因为它也会开箱即用。您需要使用React和Amp提供和/或推荐的HTTP库。

由于您的最终目标只是处理HTTP请求,因此也可以不使用这些框架中的任何一个,只使用curl_multi函数。不过它们有点难以使用。

我回答自己的问题是为了帮助其他用户,但这个解决方案是在没有经验丰富的程序员帮助的情况下单独开发的,所以我不知道它最终是否是最好的方法。

TL;DR

我从ReactPHP切换到使用amphp/parallel-functions,因为我不理解它,它提供了一个简化的最终用户界面。。。附带了使用此接口的示例代码。

<?php
require_once("../vendor/autoload.php");
use function AmpParallelFunctionsparallelMap;
use function AmpPromisewait;
$start = microtime(true);
$mysquare = function ($x) {
sleep($x);  // Simulates long network call
//echo $x."n";
return $x * $x;
};
print_r(wait(parallelMap([5,4,3,2,1,6,7,8,9,10], $mysquare)));
print 'Took ' . (microtime(true) - $start) . ' milliseconds.' . PHP_EOL;

示例代码在10.2秒内执行,这比运行时间最长的$mysquare((实例稍长。

在我的实际用例中,我能够在大约5秒内通过HTTP从90个不同的源获取数据。

注意事项:

amphp/parallel-functions库似乎在暗中使用线程。根据我的初步经验,这似乎需要比单线程PHP脚本更多的内存,但我还没有确定其全部影响。当我通过";使用($myarray(";表达和阵列为65Mb。这使代码陷入停滞,执行时间呈指数级增长,比同步执行长了几个数量级。此外,内存使用量在5G以上达到峰值!有一点让我相信amphp在为每个实例复制$myarray。修改我的代码以避免";使用($myarray(";表达式解决了这个问题。

最新更新