企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# setDefer 机制 [TOC] 绝大部分协程组件,都支持了`setDefer`特性。可以将请求响应式的接口拆分为两个步骤,使用此机制可以实现先发送数据, 再并发收取响应结果。 由于大多数情况下, \[建立连接和发送数据的耗时\] 相比于 \[等待响应的耗时\] 来说可以忽略不计, 所以可以简单理解为defer模式下, 多个客户端的请求响应是并发的 以`HttpClient`为例,设置`setDefer(true)`后,发起`$http->get()`请求,将不再等待服务器返回结果,而是在`send request`之后,立即返回`true`。在此之后可以继续发起其他`HttpClient`、`MySQL`、`Redis`等请求。最后再使用`$http->recv()`接收响应内容。 相比`子协程 + Channel`的实现方式,`setDefer`更简单一些。 > 需注意的是, defer特性只支持并发收取响应结果, 正如示例代码所示, 创建连接和数据的发送, 仍是串行的 ## 示例代码 ~~~ <?php $server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE); $server->set([ 'worker_num' => 1, ]); $server->on('Request', function ($request, $response) { $tcpclient = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); $tcpclient->connect('127.0.0.1', 9501,0.5) $tcpclient->send("hello world\n"); $redis = new Swoole\Coroutine\Redis(); $redis->connect('127.0.0.1', 6379); $redis->setDefer(); $redis->get('key'); $mysql = new Swoole\Coroutine\MySQL(); $mysql->connect([ 'host' => '127.0.0.1', 'user' => 'user', 'password' => 'pass', 'database' => 'test', ]); $mysql->setDefer(); $mysql->query('select sleep(1)'); $httpclient = new Swoole\Coroutine\Http\Client('0.0.0.0', 9599); $httpclient->setHeaders(['Host' => "api.mp.qq.com"]); $httpclient->set([ 'timeout' => 1]); $httpclient->setDefer(); $httpclient->get('/'); $tcp_res = $tcpclient->recv(); $redis_res = $redis->recv(); $mysql_res = $mysql->recv(); $http_res = $httpclient->recv(); $response->end('Test End'); }); $server->start(); ~~~ * [示例代码](https://wiki.swoole.com/wiki/page/604.html#entry_h2_0)