php循环套循环

PHP developers are always waiting for something. Sometimes we’re waiting for requests to remote services. Sometimes we’re waiting for databases to return rows from a complex query. Wouldn’t it be great if we could do other things during all that waiting?

PHP开发人员总是在等待某些东西。 有时我们正在等待对远程服务的请求。 有时我们在等待数据库从复杂的查询返回行。 如果我们能在所有等待中做其他事情不是很好吗?

If you’ve written some JS, you’re probably familiar with callbacks and DOM events. And though we have callbacks in PHP, they don’t work in quite the same way. That’s thanks to a feature called the event loop.

如果您已经编写了一些JS,则可能熟悉回调和DOM事件。 尽管我们在PHP中有回调,但它们的工作方式并不完全相同。 这要归功于称为事件循环的功能。

We’re going to look at how the event loop works, and how we can use the event loop in PHP.

我们将研究事件循环如何工作,以及如何在PHP中使用事件循环。

We’re going to see some interesting PHP libraries. Some would consider these not yet stable enough to use in production. Some would consider the examples presented as “better to do in more mature languages”. There are good reasons to try these things. There are also good reasons to avoid these things in production. The purpose of this post is to highlight what’s possible in PHP.

我们将看到一些有趣PHP库。 有些人会认为这些还不够稳定,无法在生产中使用。 有些人会认为这些示例“更好地使用更成熟的语言”。 有充分的理由尝试这些事情。 也有充分的理由避免在生产中使用这些方法。 这篇文章的目的是强调PHP中的功能。

等待的地方 (Where Things Go To Wait)

To understand event loops, let’s look at how they work in the browser. Take a look at this example:

要了解事件循环,让我们看一下事件循环在浏览器中的工作方式。 看一下这个例子:

function fitToScreen(selector) {
var element = document.querySelector(selector);
var width = element.offsetWidth;
var height = element.offsetHeight;
var top = "-" + (height / 2) + "px";
var left = "-" + (width / 2) + "px";
var ratio = getRatio(width, height);
setStyles(element, {
"position": "absolute",
"left": "50%",
"top": "50%",
"margin": top + " 0 0 " + left,
"transform": "scale(" + ratio + ", " + ratio + ")"
});
}
function getRatio(width, height) {
return Math.min(
document.body.offsetWidth / width,
document.body.offsetHeight / height
);
}
function setStyles(element, styles) {
for (var key in styles) {
if (element.style.hasOwnProperty(key)) {
element.style[key] = styles[key];
}
}
}
fitToScreen(".welcome-screen");

This code requires no extra libraries. It will work in any browser that supports CSS scale transformations. A recent version of Chrome should be all you need. Just make sure the CSS selector matches an element in your document.

此代码不需要额外的库。 它可以在任何支持CSS缩放转换的浏览器中使用。 您需要的只是Chrome的最新版本。 只需确保CSS选择器与文档中的元素匹配即可。

These few functions take a CSS selector and center and scale the element to fit the screen. What would happen if we threw an Error inside that for loop? We’d see something like this…

这几个功能采用CSS选择器并居中并缩放元素以适合屏幕。 如果我们在该for循环中抛出Error ,将会发生什么? 我们会看到这样的东西……

We call that list of functions a stack trace. It’s what things look like inside the stack browsers use. They’ll handle this code in steps…

我们将该函数列表称为堆栈跟踪。 这就是浏览器内部使用的堆栈外观。 他们将逐步处理此代码…

This is like how PHP uses a stack to store context. Browsers go a step further and provide WebAPIs for things like DOM events and Ajax callbacks. In its natural state, JavaScript is every bit as asynchronous as PHP. That is: while both look like they can do many things at once, they are single threaded. They can only do one thing at a time.

这就像PHP如何使用堆栈来存储上下文。 浏览器更进一步,为诸如DOM事件和Ajax回调之类的事情提供WebAPI。 在自然状态下,JavaScript与PHP一样异步。 那就是:虽然看起来它们都可以一次完成很多事情,但是它们都是单线程的。 他们一次只能做一件事。

With the browser WebAPIs (things like setTimeout and addEventListener) we can offload parallel work to different threads. When those events happen, browsers add callbacks to a callback queue. When the stack is next empty, browses pick the callbacks up from the callback queue and execute them.

使用浏览器WebAPI(诸如setTimeout和addEventListener之类的东西),我们可以将并行工作卸载到不同的线程。 当这些事件发生时,浏览器会将回调添加到回调队列中。 当堆栈下一个为空时,浏览器从回调队列中选择回调并执行它们。

This process of clearing the stack, and then the callback queue, is the event loop.

清除堆栈,然后清除回调队列的过程是事件循环。

没有事件循环的生活 (Life Without An Event Loop)

In JS, we can run the following code:

在JS中,我们可以运行以下代码:

setTimeout(function() {
console.log("inside the timeout");
}, 1);
console.log("outside the timeout");

When we run this code, we see outside the timeout and then inside the timeout in the console. The setTimeout function is part of the WebAPIs that browsers give us to work with. When 1 millisecond has passed, they add the callback to the callback queue.

运行此代码时,我们会outside the timeout inside the timeout看到,然后inside the timeout控制台中看到outside the timeoutsetTimeout函数是浏览器提供给我们使用的WebAPI的一部分。 1毫秒过去后,他们将回调添加到回调队列中。

The second console.log completes before the one from inside the setTimeout starts. We don’t have anything like setTimeout in standard PHP, but if we had to try and simulate it:

第二个console.logsetTimeout内部的一个console.log开始之前完成。 我们在标准PHP中没有类似setTimeout东西,但是如果我们不得不尝试对其进行仿真:

function setTimeout(callable $callback, $delay) {
$now = microtime(true);
while (true) {
if (microtime(true) - $now > $delay) {
$callback();
return;
}
}
}
setTimeout(function() {
print "inside the timeout";
}, 1);
print "outside the timeout";

When we run this, we see inside the timeout and then outside the timeout. That’s because we have to use an infinite loop inside our setTimeout function to execute the callback after a delay.

运行此命令时,我们会inside the timeout看到,然后outside the timeout 。 这是因为我们必须在setTimeout函数内使用无限循环才能在延迟后执行回调。

It may be tempting to move the while loop outside of setTimeout and wrap all our code in it. That might make our code feel less blocking, but at some point we’re always going to be blocked by that loop. At some point we’re going to see how we can’t do more than a single thing in a single thread at a time.

while循环移到setTimeout外部并将所有代码包装在其中可能很诱人。 这可能会使我们的代码减少阻塞,但是在某些时候,我们总是会被该循环阻塞。 在某个时候,我们将看到如何一次只能在单个线程中完成一件事情。

While there is nothing like setTimeout in standard PHP, there are some obscure ways to implement non-blocking code alongside event loops. We can use functions like stream_select to create non-blocking network IO. We can use C extensions like EIO to create non-blocking filesystem code. Let’s take a look at libraries built on these obscure methods…

尽管在标准PHP中没有类似setTimeout东西,但是有一些晦涩的方法可以在事件循环旁边实现非阻塞代码。 我们可以使用类似stream_select功能来创建非阻塞网络IO。 我们可以使用EIO之类的C扩展来创建非阻塞文件系统代码。 让我们看一下基于这些晦涩方法的库…

冰柱 (Icicle)

Icicle is library of components built with the event loop in mind. Let’s look at a simple example:

冰柱是考虑到事件循环而构建的组件库。 让我们看一个简单的例子:

use Icicle\Loop;
Loop\timer(0.1, function() {
print "inside timer";
});
print "outside timer";
Loop\run();

This is with icicleio/icicle version 0.8.0.

这是icicleio/icicle版本0.8.0版本。

Icicle’s event loop implementation is great. It has many other impressive features; like A+ promises, socket, and server implementations.

冰柱的事件循环实现很棒。 它具有许多其他令人印象深刻的功能; 如A + promise,套接字和服务器实现。

Icicle also uses generators as co-routines. Generators and co-routines are a different topic, but the code they allow is beautiful:

冰柱还使用生成器作为协同例程。 生成器和协同例程是不同的主题,但是它们所允许的代码很漂亮:

use Icicle\Coroutine;
use Icicle\Dns\Resolver\Resolver;
use Icicle\Loop;
$coroutine = Coroutine\create(function ($query, $timeout = 1) {
$resolver = new Resolver();
$ips = (yield $resolver->resolve(
$query, ["timeout" => $timeout]
));
foreach ($ips as $ip) {
print "ip: {$ip}\n";
}
}, "sitepoint.com");
Loop\run();

This is with icicleio/dns version 0.5.0.

这是icicleio/dns版本0.5.0

Generators make it easier to write asynchronous code in a way that resembles synchronous code. When combined with promises and an event loop, they lead to great non-blocking code like this!

生成器使它更容易以类似于同步代码的方式编写异步代码。 当与promise和事件循环结合使用时,它们会导致像这样的出色的非阻塞代码!

ReactPHP (ReactPHP)

ReactPHP has a similar event loop implementation, but without all the interesting generator stuff:

ReactPHP具有类似的事件循环实现,但没有所有有趣的生成器内容:

$loop = React\EventLoop\Factory::create();
$loop->addTimer(0.1, function () {
print "inside timer";
});
print "outside timer";
$loop->run();

This is with react/event-loop version 0.4.1.

这是带有react/event-loop版本0.4.1版本。

ReactPHP is more mature than Icicle, and it has a larger range of components. Icicle has a way to go before it can contend with all the functionality ReactPHP offers. The developers are making good progress, though!

ReactPHP比Icicle更成熟,并且具有更大范围的组件。 冰柱要想与ReactPHP提供的所有功能抗衡,还有一段路要走。 不过,开发人员正在取得良好进展!

结论 (Conclusion)

It’s difficult to get out of the single-threaded mindset that we are taught to have. We just don’t know the limits of code we could write if we had access to non-blocking APIs and event loops.

很难摆脱我们被教导拥有的单线程思维方式。 如果我们可以访问非阻塞API和事件循环,我们只是不知道可以编写的代码限制。

The PHP community needs to become aware of this kind of architecture. We need to learn and experiment with asynchronous and parallel execution. We need to pirate these concepts and best-practices from other languages who’ve had event loops for ages, until “how can I use the most system resources, efficiently?” is an easy question to answer with PHP.

PHP社区需要意识到这种架构。 我们需要学习和尝试异步和并行执行。 我们需要从具有事件循环年龄的其他语言中盗用这些概念和最佳实践,直到“我如何才能有效地利用最多的系统资源?” 用PHP回答一个简单的问题。

Stay tuned for a more practical implementation of Icicle, coming soon!

请继续关注Icicle的更实际实现,即将推出!

翻译自: https://www.sitepoint.com/an-introduction-into-event-loops-in-php/

php循环套循环

php循环套循环_PHP中的事件循环简介相关推荐

  1. for循环延时_前端中的事件循环eventloop机制

    我们知道 js 是单线程执行的,那么异步的代码 js 是怎么处理的呢?例如下面的代码是如何进行输出的: console.log(1);setTimeout(function() { console.l ...

  2. 浏览器中的事件循环机制

    浏览器中的事件循环机制 网上一搜事件循环, 很多文章标题的前面会加上 JavaScript, 但是我觉得事件循环机制跟 JavaScript 没什么关系, JavaScript 只是一门解释型语言, ...

  3. 5.node.js中的事件循环

    先举一个简单的例子 const bar = () => console.log('bar')const baz = () => console.log('baz')const foo = ...

  4. js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制

    虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...

  5. JavaScipt 中的事件循环(event loop),以及微任务 和宏任务的概念

    说事件循环(event loop)之前先要搞清楚几个问题. 1. js为什么是单线程的? 试想一下,如果js不是单线程的,同时有两个方法作用dom,一个删除,一个修改,那么这时候浏览器该听谁的? 2. ...

  6. php event loop,理解javascript中的事件循环(Event Loop)

    背景 在研究js的异步的实现方式的时候,发现了JavaScript 中的 macrotask 和 microtask 的概念.在查阅了一番资料之后,对其中的执行机制有所了解,下面整理出来,希望可以帮助 ...

  7. js中的事件循环和宏任务和微任务的理解

    参考许多大神的文章,写下自己的理解 事件循环: 说到事件循环就得谈到js中同步和异步的执行顺序 1.javascript将任务分为同步任务和异步任务,同步任务放到主线中,异步函数首先进行回调函数注册. ...

  8. 详解队列在前端的应用,深剖JS中的事件循环Eventloop,再了解微任务和宏任务

    队列在前端中的应用 一.队列是什么 二.应用场景 三.前端与队列:事件循环与任务队列 1.event loop 2.JS如何执行 3.event loop过程 4. DOM 事件和 event loo ...

  9. 【nodejs原理源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    [摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...

最新文章

  1. 前端面试问题(持续更新)
  2. 随堂小测app(nabcd)
  3. 再来一次的C语言贪吃蛇小游戏(二)
  4. css中光标的设置,CSS Cursors(光标)
  5. qt git linux 安装,git – 如何在Ubuntu上安装QtWebEngine
  6. 光影的魔法!Cocos Creator 实现屏幕空间的环境光遮蔽(SSAO)
  7. copy_{to, from}_user()的思考
  8. Aspose.Cells使用总结大全
  9. 编译源码时出现 Checking API: checkapi-last (unknown): error 17解决方法
  10. 19.UNIX 环境高级编程--伪终端
  11. IOCAutofac与ORMEntityFramwork的联系--单例模式
  12. EPS学习笔记2----------常用地物绘制基础
  13. 所谓“卡常数”的常数到底指什么?
  14. CentOS官方免费下载地址,包含CentOS7和CentOS8
  15. php codeigniter insert,codeigniter批量插入数据(示例)
  16. !HDU 4311 最小曼哈顿距离-思维卡时间-(横纵坐标分开算,排序)
  17. 移动端 click 300ms 延迟,如何解决
  18. day07 Java链表(环、快慢指针)
  19. 精伦的开发盒子USB上外挂SD卡路径
  20. 27年台湾珍珠鲜奶茶品牌Sharetea将引进上海

热门文章

  1. 互联网行业的一些英文简称(缩写),别人家一说你又懵了!
  2. Longitudinal Statistics 纵向统计分析
  3. 第一章 数据仓库理论专题
  4. 行人轨迹论文:STUGCN:A Social Spatio-Temporal Unifying Graph Convolutional Network for Trajectory Predictio
  5. android银行卡输入密码,android 仿微信添加银行卡时输入支付密码
  6. vue自适应多行文本
  7. 微信小程序--优购商城项目(6)
  8. QT之Excel表格操作
  9. Excel批量选中表格中所有图片
  10. 树莓派3强大很多--相比树莓派2