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实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例)
- mysql5.7.19下载及安装教程(Apache2.2.16+PHP5.3.3+MySQL5.1.49的配置方法)
- php怎么根据字符串长度设置(php常用字符串长度函数strlen与mb_strlen用法实例分析)
- thinkphp5对接支付宝扫码支付(ThinkPHP框架下整合支付宝支付功能图文教程)
- phpstudy显示403(phpStudy配置多站点多域名方法及遇到的403错误解决方法)
- php日期和时间怎么设置(PHP实现时间日期友好显示实现代码)
- php八大模式详解(php设计模式之工厂模式用法经典实例分析)
- phpstudy如何部署在linux上(phpstudy linux面板CC防护功能使用教程)
- php如何实现异步调用(php基于协程实现异步的方法分析)
- phpstudy怎么修改mysql版本(PhpStudy集成环境升级MySQL数据库版本的方法)
- centos安装php5.6(Centos7 Yum安装PHP7.2流程教程详解)
- php入门教程源代码修改教程(php+js实现的无刷新下载文件功能示例)
- php错误提示问题(php提示Creating default object from empty value 的问题解决方法)
- php函数的使用方法(PHP中str_split函数的用法讲解)
- thinkphp5框架分析(thinkPHP5框架路由常用知识点汇总)
- php和xml有什么关系(PHP创建XML的方法示例基于DOMDocument类及SimpleXMLElement类)
- 经常发这三种 朋友圈 的人,要迅速屏蔽(经常发这三种朋友圈)
- 有种尴尬叫朋友圈忘屏蔽,大学生上演社死现场,父母亲自下场吐槽(有种尴尬叫朋友圈忘屏蔽)
- 朋友圈屏蔽你的人,可以直接看淡了(朋友圈屏蔽你的人)
- 金球奖只青睐那些会戴珠宝的女人(金球奖只青睐那些会戴珠宝的女人)
- 浙江省一个县,人口超40万,建县历史超1100年(浙江省一个县人口超40万)
- 五代十国南唐历代国君(五代十国南唐历代国君)
热门推荐
- 谷歌浏览器调试模式下搜索小技巧
- sql function用法(SQL Function 自定义函数详解)
- ftp服务器登录错误(登陆FTP服务器提示530 Login authentication failed 错误的解决方法)
- dedecms屏蔽规则(织梦dedecms修改任意管理员漏洞处理方法)
- canvas如何调试(关于canvas.toDataURL 在iOS运行失败的问题解决)
- easyUI DataGrid 显示可排序的列
- ftp服务器怎么搭建linux(Linux下使用vsftp搭建FTP服务器附参数说明)
- vue渲染数据的过程(Vue前端高效开发之列表渲染指令)
- 数据库常见的索引结构(数据库索引知识点整理)
- 微信小程序计时器(微信小程序实现简单的计算器功能)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9