Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于中间件匿名函数中的 yield true #3

Closed
m9rco opened this issue Oct 25, 2017 · 2 comments
Closed

关于中间件匿名函数中的 yield true #3

m9rco opened this issue Oct 25, 2017 · 2 comments

Comments

@m9rco
Copy link

m9rco commented Oct 25, 2017

杨老师您好
最近在学习owl项目,看到在闭包中引用yield true语句,这里似乎理解的不太明白,在以前的学习中一直理解为在使用yield关键字后的语句不会被立即执行,而是放入某个缓冲区,等待下一次在while 或者foreach调用时启用,这时多个代码块会并发执行,来达到协程效果,其在cpu级处于快速切换那什么实现..然后看到这里yield true表示不太理解,您若有时间敬请赐教哦,感激不尽

 * $app->middleware(function($request, $response) {
 *     $start = microtime(true);
 *
 *     yield true;
 *
 *     $use_time = (microtime(true) - $start) * 1000;
 *     $response->withHeader('use-time', (int)$use_time.'ms');
 * });
@m9rco m9rco changed the title 关于中间件闭包函数中的 yield true 关于中间件匿名函数中的 yield true Oct 25, 2017
@yeaha
Copy link
Owner

yeaha commented Oct 25, 2017

这里并没有让代码并发执行,仅仅是一种跳出去再跳回来的跳转逻辑而已,算不上协程。
用yield实现并发的协程,语言要支持异步的IO或者计算才行,PHP在这一块的支持是很薄弱的。

对多个middleware的调用逻辑可以看\Owl\Middleware的execute()方法 (https://github.com/yeaha/owl-core/blob/master/src/Middleware.php#L69)

简单说明一下流程就是:

  1. 依次call每个middleware function
  2. 观察返回值是否一个Generator对象,因为允许middleware执行一次完事,不用再跳进去
  3. 调用Generator::current()检查返回值,如果是false说明这个middleware逻辑决定中断整个链条继续执行
  4. 把拿到的Generator放到一个先进后出的栈里
  5. 所有middleware执行完之后,把依次调用栈里的Generator::next()方法执行每个middleware剩余逻辑

@m9rco
Copy link
Author

m9rco commented Oct 25, 2017

哇撒,谢谢杨老师 🎉

@yeaha yeaha closed this as completed Oct 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants