php 实现 Promise.all 和 Promise.race

何一鸣何一鸣 -
php 实现 Promise.all 和 Promise.race

测试

$promise1 = function () {
  msleep(500);
  return 'one';
};
$promise2 = function () {
  msleep(100);
  return 'two';
};
$promise3 = function () {
  msleep(50);
  throw new \Exception('Reject');
};
var_dump(promise_all([$promise1, $promise2]));
var_dump(promise_race([$promise1, $promise2]));
var_dump(promise_race([$promise1, $promise2, $promise3]));

结果

# php promise.php
array(2) {
[1]=>
string(3) "two"
[0]=>
string(3) "one"
}
string(3) "two"
object(Exception)#15 (7) {}

实现

<?php

declare(strict_types=1);

use Swow\Coroutine;
use Swow\Channel;
use Swow\Sync\WaitGroup;
use function Swow\defer;

/**
 * @param array $callbacks 
 * @param int $parallel 并发数量
 * @return array 
 */
function promise_all(array $callbacks, int $parallel = -1)
{
  $wg = new WaitGroup();
  $channel = new Channel($parallel);
  $results = [];
  foreach ($callbacks as $key => $callback) {
      $wg->add();
      $channel->push(true);
      Coroutine::run(static function () use ($wg, $channel, $callback, $key, &$results) {
          try {
              $results[$key] = $callback();
          } catch (\Throwable) {
          } finally {
              $channel->pop();
              $wg->done();
          }
      });
  }
  $wg->wait();
  return $results;
}

/**
 * @param array $callbacks
 * @param int $timeout 超时
 * @param bool $throw 是否抛出异常
 * @return mixed
 */
function promise_race(array $callbacks, int $timeout = -1, bool $throw = true): mixed
{
  $coroutines = [];
  defer(static function () use (&$coroutines) {
      foreach ($coroutines as $coroutine) {
          if ($coroutine->isExecuting()) {
              $coroutine->kill();
          }
      }
  });
  $channel = new Channel();
  foreach ($callbacks as $callback) {
      $coroutines[] = Coroutine::run(static function () use ($channel, $callback) {
          try {
              $channel->push($callback());
          } catch (\Throwable $e) {
              $channel->push($e);
          }
      });
  }
  try {
      return $channel->pop($timeout);
  } catch (\Throwable $e) {
      if ($throw) {
          throw $e;
      }
  }
  return false;
}
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

php介绍

PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。

Tags 标签

phppromisecoroutineswow协程

扩展阅读

加个好友,技术交流

1628738909466805.jpg