php如何实现异步调用(php基于协程实现异步的方法分析)
类别:编程学习 浏览量:2189
时间:2022-01-18 01:48:56 php如何实现异步调用
php基于协程实现异步的方法分析本文实例讲述了php基于协程实现异步的方法。分享给大家供大家参考,具体如下:
github上php的协程大部分是根据这篇文章实现的:http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html。
它们最终的结果都是把回调变成了优雅的顺序执行的代码,但还是阻塞的,不是真正的异步。
比如最热门的:https://github.com/recoilphp/recoil
先安装:
|
composer require recoil /recoil |
执行:
|
<?php //recoil.php include __DIR__ . '/vendor/autoload.php' ; use Recoil\React\ReactKernel; $i = 100000; ReactKernel::start(task1()); ReactKernel::start(task2()); function task1(){ global $i ; echo "wait start" . PHP_EOL; while ( $i -- > 0) { yield; } echo "wait end" . PHP_EOL; }; function task2(){ echo "Hello " . PHP_EOL; yield; echo "world!" . PHP_EOL; } |
结果:
wait start
//等待若干秒
wait end
Hello
world!
我本来是想让两个任务并行,结果两个任务变成了串行,中间等待的时间什么事情都干不了。React响应式的编程是严格禁止这种等待的,所以我就参照unity3d的协程自己写了个php版本的。上代码:
|
<?php //Coroutine.php //依赖swoole实现的定时器,也可以用其它方法实现定时器 class Coroutine { //可以根据需要更改定时器间隔,单位ms const TICK_INTERVAL = 1; private $routineList ; private $tickId = -1; public function __construct() { $this ->routineList = []; } public function start(Generator $routine ) { $task = new Task( $routine ); $this ->routineList[] = $task ; $this ->startTick(); } public function stop(Generator $routine ) { foreach ( $this ->routineList as $k => $task ) { if ( $task ->getRoutine() == $routine ){ unset( $this ->routineList[ $k ]); } } } private function startTick() { swoole_timer_tick(self::TICK_INTERVAL, function ( $timerId ){ $this ->tickId = $timerId ; $this ->run(); }); } private function stopTick() { if ( $this ->tickId >= 0) { swoole_timer_clear( $this ->tickId); } } private function run() { if ( empty ( $this ->routineList)){ $this ->stopTick(); return ; } foreach ( $this ->routineList as $k => $task ) { $task ->run(); if ( $task ->isFinished()){ unset( $this ->routineList[ $k ]); } } } } class Task { protected $stack ; protected $routine ; public function __construct(Generator $routine ) { $this ->routine = $routine ; $this ->stack = new SplStack(); } /** * [run 协程调度] * @return [type] [description] */ public function run() { $routine = & $this ->routine; try { if (! $routine ){ return ; } $value = $routine ->current(); //嵌套的协程 if ( $value instanceof Generator) { $this ->stack->push( $routine ); $routine = $value ; return ; } //嵌套的协程返回 if (! $routine ->valid() && ! $this ->stack->isEmpty()) { $routine = $this ->stack->pop(); } $routine ->next(); } catch (Exception $e ) { if ( $this ->stack->isEmpty()) { /* throw the exception */ return ; } } } /** * [isFinished 判断该task是否完成] * @return boolean [description] */ public function isFinished() { return $this ->stack->isEmpty() && ! $this ->routine->valid(); } public function getRoutine() { return $this ->routine; } } |
测试代码:
|
<?php //test.php require 'Coroutine.php' ; $i = 10000; $c = new Coroutine(); $c ->start(task1()); $c ->start(task2()); function task1(){ global $i ; echo "wait start" . PHP_EOL; while ( $i -- > 0) { yield; } echo "wait end" . PHP_EOL; }; function task2(){ echo "Hello " . PHP_EOL; yield; echo "world!" . PHP_EOL; } |
结果:
wait start
Hello
world!
//等待几秒,但不阻塞
wait end
希望本文所述对大家PHP程序设计有所帮助。
原文链接:https://blog.csdn.net/llj1985/article/details/51684210
您可能感兴趣
- php抽奖功能(php+lottery.js实现九宫格抽奖功能)
- php 创建定时任务(PHP扩展Swoole实现实时异步任务队列示例)
- php生成随机数讲解(PHP生成随机字符串实例代码字母+数字)
- phpstudy怎么配置域名并访问(phpstudy怎么绑定目录实现域名访问)
- php探针哪个牌子好用(php探针使用原理和技巧讲解)
- thinkphp5框架怎么设置(thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例)
- php验证码实现过程(php伪静态验证码不显示的解决方案)
- php读取远程的txt文件(php 根据URL下载远程图片、压缩包、pdf等文件到本地)
- phpstudy修改为什么进不去(phpstudy2018升级后站点及phpmyadmin打开404解决方案)
- php获取数组中和为指定数的数组(php统计数组不同元素的个数的实例方法)
- php实现redis消息队列(redis+php实现微博三微博列表功能详解)
- php设计模式如何实现(php模式设计之观察者模式应用实例分析)
- php性能优化的思路和步骤(FastCGI轻松搞定IIS7.5+PHP5.6.0环境)
- php数据错误处理函数(php中错误处理操作实例分析)
- phplaravel快速开发平台(laravel框架实现去掉URL中index.php的方法)
- phpstudy不解析php代码(phpstudy伪静态设置的问题)
- 营养餐是什么(学校营养餐是什么)
- 谁说女子不如男 范冰冰演的武则天只是其一,另外两位你认识吗(谁说女子不如男)
- 杯酒人生---瓦伦丁酒杯和奥丁格啤酒(杯酒人生---瓦伦丁酒杯和奥丁格啤酒)
- 中秋节买啤酒,预算超过7元试试这8种啤酒,麦香浓郁都是真啤酒(预算超过7元试试这8种啤酒)
- CellPress旗下的6 期刊,国人友刊来了解一下吧(CellPress旗下的6期刊国人友刊来了解一下吧)
- ()
热门推荐
- mysql中delete聚合函数查询值(MySQL 分组查询和聚合函数)
- 阿里云ftp搭建(阿里云服务器搭建FTP服务器图文教程windows)
- dedecms调用logo标签(dedecms返回列表页功能的标签代码)
- mysql各种备份方式(MySQL 逻辑备份与恢复测试的相关总结)
- nginx结构图解(详解Nginx 工作原理)
- 用css实现图片特效代码(HTML+CSS+JavaScript实现图片3D展览的示例代码)
- 香港服务器有哪些优势呢(浅谈香港服务器与香港云主机的区别)
- windowsmysql服务在哪里(解决windows service 2012阿里云服务器在搭建mysql时缺少msvcr100.dll文件的问题)
- dockerhub镜像排行(DockerHub 镜像仓库的使用详解)
- sqlserver字符串截取填充(SQL Server实现split函数分割字符串功能及用法示例)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9