PHP 事件 (Ev 系列)
参考文章
Ev 扩展
Ev 进程控制扩展使用范例
事件: JavaScript Vs PHP
JavaScript 事件window.addEventListener('click',function(){
console.log("屏幕点击事件");
},false);
console.log("不会阻塞, 你会立即看到我");
打开浏览器控制台查看, 你会发现: js 并没有在定义完 click 事件后就一直在那儿监听事件是否触发, 一旦触发运行回调函数而导致进程阻塞在那儿!
而是继续执行下去, 先输出 不会阻塞, 你会立即看到我
如果 Js 代码就是上面几行, 执行完代码的最后一行后, 你点击屏幕他会触发 click 回调函数吗?? 答案是: 会!
总结一下 js 事件的特点:
不会阻塞进程, 仅在满足条件时执行回调函数
即使执行完代码的最后一行, 进程依旧在! 事件依旧可触发
PHP 事件// 每隔 0.2s 执行一次
$t=newEvTimer(2,false,function(){
var_dump('2s time over\n');
});
var_dump('run!');
// 执行
Ev::run();
var_dump("over!");
上述程序运行后, 输出结果如下:run!
// 2s 后输出
2stime over
over!
这表明程序会阻塞在 Ev::run 这一行, 直到 2s 过后才会继续执行! 这和 Js 的事件相比, 简直糟糕透了! 灵活性太差! 说起来就是 PHP 太笨了! 不懂得先往下做, 到时间点再回来执行定时器指定回调!
如果代码更新成下面这种:$t=newEvTimer(0.2,true,function(){
var_dump('0.2s time over\n');
});
var_dump('start!');
Ev::run();
var_dump('over!');
上述程序运行后, 输出结果如下:start!
// 0.2s 后输出
0.2stime over
// 同上
0.2stime over
0.2stime over
0.2stime over
....
这再次表明程序会阻塞在 Ev::run 那一行! 总结: PHP 笨!!
代码再次更新如下:$t=newEvTimer(2,false,function(){
var_dump('2s time over\n');
});
var_dump('start!');
// 不阻塞进程执行
Ev::run(Ev::RUN_NOWAIT);
var_dump('end!');
上述程序输出如下:
start! end!
程序并没有在执行到代码的最后一行的时候, 继续等待定时事件, 而是直接结束了进程! 类比 Js: 即使代码执行到了最后一行, 事件监听仍在! PHP 这个傻吊就是不懂他还有事件未做完不能退出!
代码再次更新如下:$t=newEvTimer(5,false,function(){
var_dump('5s time over!\n');
});
var_dump('start!');
Ev::run(Ev::RUN_NOWAIT);
var_dump('end!');
$t1=newEvTimer(0.2,true,function(){
var_dump("0.2s time over!\n");
});
var_dump('start again!\n');
Ev::run();
var_dump('end again!\n');
上述程序输出如下:start!
end!
0.2stime over!
start again
0.2stime over!
0.2stime over!
0.2stime over!
...
// 5s 时间到了后
5stime over!
0.2stime over!
0.2stime over!
...
这边注册了两个定时事件, 类型不同: 第一个不阻塞第二个阻塞结果表明, PHP 事件如果采用异步方式定义, 则需要自行控制进程退出, 否则注册的事件可能无效 ...., 总结: PHP 笨!
以上总结如下:
PHP 事件可选控制阻塞模式, 如果设置了非阻塞模式, 那么需要自行控制进程退出
PHP 不会管事件是否存在, 只要代码成功执行完了最后一行, 进程就会退出!
Ev 系列函数介绍
Ev, 静态类, 默认循环的访问和常见操作
run, 开启事件循环监听
...
EvTimer, 定时器
EvIo, 文件描述符资源流监听
....
有错欢迎纠正, 未完待续.....
来源: https://segmentfault.com/a/1190000013574576