php 异步并行

如果你有一批数据需要调用远程接口处理,而远程接口处理时间很长,比如需要1秒左右,那10条数据就是10秒,你的程序就要10S才能结束,而这样的话一旦接口提供方有点问题,就需要20秒 30秒甚至更久,这样就给我们带来了极大隐患,虽然我们可以使用设置超时来避免这样的长久等待,但是如果串行化不解决的话,程序始终是要长时间等所有任务都结束才能继续判断后面的结果的。

所以这里引入异步概念,用  composer require spatie/async 安装后的 Pool 里面的create 和 async 以及await来解决问题。

例子如下:

我们接口提供方是这样的代码

<?php
sleep(1);
echo json_encode(range(1,15));
exit;

以往我们的调用是这样的

foreach (range(1, 10) as $v) {
  $list[] = file_get_contents("http://localhost/index.php?act=" . $v);
}

那就是按顺序调用接口,统计下来耗时 10021 ms 也就是10秒

现在我们可以这样做

复制代码
<?php
include "vendor/autoload.php";

use Spatie\Async\Pool;
$pool = Pool::create();
foreach (range(1, 10) as $item) {
    $pool[] = async(function () use ($item) {
      return file_get_contents("http://localhost/index.php?act=" . $item);
    })->then(function (string $output) use(&$list) {
      $list[] = $output;
    });
}
await($pool);
复制代码

发现耗时 1341 ms,也就是说基本上是9-10个在同时并行请求,节省了很多时间。

我测试了一下如果不是在循环里面调用接口,而是简单的做一个item*2的数学运算,那同步可快多了,异步可慢多了。

复制代码
<?php
include "vendor/autoload.php";

use Spatie\Async\Pool;
$pool = Pool::create();
foreach (range(1, 10) as $item) {
    $pool[] = async(function () use ($item) {
      return $item * 2;
    })->then(function (string $output) use(&$list) {
      $list[] = $output;
    });
}
await($pool);
复制代码

耗时 324 ms

而同步的嘛,只要 0.0019 ms

<?php
foreach (range(1, 10) as $v) {
  $list[] = 2 * $v;
}

毕竟这种情况下多余的异步开销反而不如同步啊。

适用场景就是多数据量,长耗时任务被阻塞等待,那这个时候用这个东西缓解一下压力,提高一下速度还是不错的。

posted @   李照耀  阅读(509)  评论(6编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
历史上的今天:
2016-09-02 递归方式将数组变对象
2016-09-02 中文编码与解码
2016-09-02 过滤字符串中的空格
点击右上角即可分享
微信分享提示