zoukankan      html  css  js  c++  java
  • 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 SpatieAsyncPool;
    $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 SpatieAsyncPool;
    $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;
    }

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

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

  • 相关阅读:
    甩掉DataList,Repeater,列表数据显示得灵活
    拟将《汉字速查》更名为《汉文博士》,诸位有何高见?
    新一版的汉文博士(0.5.2.1210)已经发布
    新一版的汉文博士(0.5.1.1070)已经发布
    EditPlus 3.5 版已经发布
    如何在计算机和汉字速查界面上显示七万个汉字
    使用汉字构形检索疑难字
    软件使用方法及界面截图
    Unihan 里的笔画数据有问题?
    循序渐进制作我的词典数据库(一)
  • 原文地址:https://www.cnblogs.com/lizhaoyao/p/15217805.html
Copyright © 2011-2022 走看看