Swoole官方文档中的协程例子,大部分都是以一次请求一个协程(或者大量并发脚本)的方式来说明的。这样提高的是整体性能,而不是单个请求的响应时间。.提高单个请求的响应效率(或者提高非网络服务下php脚本代码的运行效率),需要在业务代码中积极使用协程来处理并发耗时的代码。这里涉及到协程数据交互的情况,官方文档中使用chan来举例一个生产者和消费者,但是如果业务代码遵循这种风格,就比较复杂了。js和c#的async/await风格使用起来比较简单,所以结合Swoole协议将进程的csp模型和php语法在async/await的风格中简单封装如下。封装方法代码classCoTask{protected$chan=null;公共函数__construct(\Chan$chan){$this->chan=$chan;}publicfunctionwait(){if($this->chaninstanceof\Chan){$result=$this->chan->pop();$this->chan=null;if(!empty($result['exception'])&&$result['exception']instanceof\Throwable){throw$result['exception'];}else{返回$result['result'];}}else{thrownew\Exception('异常');}}}functionco_run($func){$chan=new\Chan(1);$task=new\CoTask($chan);去(函数()使用($chan,$func){$result=['result'=>null,'exception'=>null];试试{$result['result']=$func();}catch(\Throwable$e){$result['exception']=$e;}$chan->push($result);});返回$task;}functionco_wait(&$task){if($taskinstanceof\CoTask){$task=$task->wait();}return$task;}调用示例$test=co_run(function(){//执行代码并返回结果});//执行其他代码co_wait($test);//由于使用了chan的pop方法,所以需要在协程上下文中var_dump($test);PHP7.4以后箭头函数调用示例$test=co_run(fn()=>"单行执行代码,如果多行还需要按原方法");//执行其他代码co_wait($test);//因为使用了chan的pop方法,所以需要当前在协程上下文中var_dump($test);经过这么简单的封装,就可以用在业务代码中存在多个并发调用或者循环调用的场景,压缩单次处理时间。
