首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法获得ReactPHP承诺异步执行

无法获得ReactPHP承诺异步执行
EN

Stack Overflow用户
提问于 2018-07-13 01:11:04
回答 2查看 1.3K关注 0票数 1

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

我一直试图学习如何执行同时或异步地获取和处理数据的函数,以便总时间是最慢调用的时间。从我的研究来看,ReactPHP或Amp是正确的工具。

但是,我在创建实际正确执行的测试代码方面没有成功。附加了一个简单的示例,mysquare()表示我的更复杂的函数。由于网络上缺少我想要实现的目标的例子,我被迫使用了一个蛮力方法,我的代码中列出了3个例子。

Q1:我在工作中使用了正确的工具吗?

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

注:我是一个真正的初学者,所以最简单的代码示例与最低水平的高级编程术语将不胜感激。

代码语言:javascript
复制
<?php
require_once("../vendor/autoload.php");

for ($i = 0; $i <= 4; $i++) {

    // Experiment 1
    $deferred[$i] = new React\Promise\Deferred(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 = React\Promise\all($deferred); // Doesn't work
$promises = React\Promise\all($promise); // Doesn't work
$promises = React\Promise\all($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);
}
EN

回答 2

Stack Overflow用户

发布于 2018-07-13 01:29:51

异步并不意味着多个线程并行执行。只有当函数(例如)执行IO (例如HTTP请求)时,才能真正在“同一时间”运行。

我们阻塞了睡眠,所以你什么也得不到。ReactPHP和Amp本身都将有某种“睡眠”功能,这是在事件循环中内置的。

出于同样的原因,您将不能只使用卷发,因为它也会被挡出方框。您需要使用反应和放大器提供和/推荐的HTTP库。

因为您的最终目标只是执行HTTP请求,所以您也不能使用这些框架中的任何一个,而只使用curl_multi函数。不过,它们有点难用。

票数 1
EN

Stack Overflow用户

发布于 2018-07-16 00:37:09

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

TL;DR

我从ReactPHP转到使用amphp/parallel-functions,它提供了简化的终端用户界面.使用此接口附加的示例代码。

代码语言:javascript
复制
<?php
require_once("../vendor/autoload.php");

use function Amp\ParallelFunctions\parallelMap;
use function Amp\Promise\wait;

$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脚本,但我还没有完全确定它的影响。当我通过"use ($myarray)“表达式将一个大数组传递给$myarray时突出显示了这一点,数组为65 to。这使代码陷入停顿,使执行时间成倍增加,以至于花费的时间比同步执行要长几个数量级。此外,内存使用高峰在5G以上!在某种程度上,这让我相信amphp是在复制每个实例的$myarray。修改我的代码以避免"use ($myarray)“表达式解决了这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51316407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档