了解事件循环 [英] Understanding the Event Loop

查看:210
本文介绍了了解事件循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想这件事,这就是我想出了:

让我们说我们有一个code是这样的:

  console.clear();
的console.log(一);
的setTimeout(函数(){的console.log(B);},1000);
的console.log(C);
的setTimeout(函数(){的console.log(D);},0);

一个请求时,和JS引擎开始执行code上面一步一步来。前两个调用是同步调用。但是,当涉及到的setTimeout 方法,它成为一个异步执行。但是JS立即返回并继续执行,这就是所谓的非阻塞异步。并继续从事其他等。

这执行结果如下:


  

一个C D B


所以基本上第二的setTimeout 完成了第一和它的回调函数得到比第一个较早的执行,这是很有意义的。

我们在这里讨论的单线程应用程序。 JS引擎一直执行此,除非它完成的第一个请求时,它不会去第二个。但好消息是,它不会等待阻塞操作像的setTimeout 来解决,因此会更快,因为它接受新传入的请求。

但我的问题,各地出现下列项目:

1 如果我们是在谈论一个单线程应用程序,那么是什么机制流程一个定时器,而JS引擎接受更多的请求,执行呢?如何单线程继续进行其他的请求工作吗?在的setTimeout ,而其他请求滚滚而来并得到执行的作品。

2:如果这些的setTimeout 功能得到更多请求来了并正在执行的幕后执行,有什么执行异步在幕后执行?这是什么东西,我们讲叫事件循环

3:但是不应该整方法放在事件循环,这样整个事情会被执行并且回调方法获取叫什么名字?这就是我理解谈论回调函数时:

 函数downloadFile(文件路径,回调)
{
  blah.downloadFile(文件路径);
  回电话();
}

但是,在这种情况下,如何对JS引擎知道这是否是一个异步函数,以便它可以把在事件循环回调?也许类似的 async`在C#或某种表明该方法的JS引擎将在一个属性的关键字是异步方法,应作相应处理。

#4:但是,一个<一个href=\"http://$c$c.tutsplus.com/tutorials/event-based-programming-what-async-has-over-sync--net-30027\">article说出乎我所猜测的事情怎么可能被工作:


  

事件循环是回调函数的队列。当一个异步
  函数执行,回调函数被推入队列中。该
  JavaScript引擎不会开始处理事件循环,直到
  code异步函数执行后。


5:并没有在这里这一形象可能是有益的,但​​图像中的第一种解释是说正是中提到的同样的事情的问题数4:

所以在这里,我的问题是,以获取有关上面列出的项目一些澄清?


解决方案

  

1:如果我们是在谈论一个单线程应用程序,那么什么处理一个定时器,而JS引擎接受更多的请求,并执行他们?这不是单独的线程将继续在其他请求工作吗?那么谁将会继续setTimeout的工作,而其他的请求不断地来,得到执行。


有只有1中的节点的过程,实际上将执行程序的JavaScript线程。然而,节点本身,其实有几个线程处理事件循环机制的运作,这包括IO线程池和其他人屈指可数。最关键的是,这些线程的数量不对应的并发连接数就像他们在一个线程,每个连接并发模型被处理。

现在关于执行一个定时器,当你调用的setTimeout ,所有节点确实基本上是更新在未来一段时间将要执行的功能的数据结构。它主要有一堆东西队列,需要做的,每一个事件循环它选择一个嘀,从队列中删除,并运行它。

要了解一个关键问题是,节点依赖于OS上最繁重的工作。所以传入网络请求实际上是由操作系统本身跟踪,当节点是否准备好处理一个它只是使用系统调用要求操作系统与准备处理数据的网络请求。这么多的IO工作的节点不要么是嘿操作系统,得到了与准备读取数据的网络连接?或者嘿OS,我的任何文件系统优秀调用有数据准备好了吗?。根据其内部算法和事件循环发动机设计,节点将选择一个JavaScript代码嘀来执行,运行它,然后重复一遍这个过程。这就是由事件循环的意思。节点基本上是在任何时候都决定什么是JavaScript代码,我应该跑下一点点?,然后运行它。这个因素在其中IO操作系统已经完成,事情已经通过调用JavaScript中被排队到的setTimeout process.nextTick


  

2:如果这些setTimeout的会在幕后,而更多的请求来了,并正在执行得到执行,那东西进行异步执行幕后的是,我们正在谈论事件循环一


没有得到的JavaScript在幕后执行。在程序中所有的JavaScript运行的前沿和中心,一次一个。会发生什么幕后是操作系统处理IO和节点等待,要做好准备,节点管理它的JavaScript等待执行的队列中。


  

3:JS引擎如何知道它是否是一个异步函数,以便它可以把它在事件循环


有是一组固定的节点中的核心是异步,因为它们使系统调用和节点都知道这些都是因为他们必须调用OS或C ++函数。基本上所有的网络和文件系统IO以及子进程的互动将是异步的唯一途径JavaScript可以得到节点异步运行的东西是通过调用该节点核心库提供的异步功能之一。即使你使用的是NPM包定义它自己的API,以产生事件循环,最终的故宫包的code将调用节点核心的异步功能之一,当节点知道蜱是完整的,它可以说是再次启动该事件循环算法


  

4事件循环是回调函数的队列。当一个异步函数执行,回调函数被推入队列中。一个异步函数执行后的JavaScript引擎不开始处理事件循环,直到code。


是的,这是事实,但它是一种误导。关键是正常的模式是:

  //假设这个code是蜱1运行
fs.readFile(/家庭/美邦/ colors.txt功能(错误数据){
  //这个回调函数内部的code绝对不会蜱1运行
  //它会在某些剔&GT运行; = 2
});
//这个code绝对会还蜱1运行
//但是,通常没有太多其他在这里做,
所以在某些时候排队了一些异步IO,这种蜱后不久//
//将一无所有有用这样做会刚刚结束,因为IO结果
//需要什么有用的东西可以做之前

所以,是的,你可以完全由刚刚都在同一个滴答计数同步所有内存斐波那契数阻止事件循环,并且是这将完全冻结你的程序。这是合作的并发性。 JavaScript代码每个标记必须产生事件循环时间一定合理数量还是整体架构失败。

I am thinking about it and this is what I came up with:

Let's say we have a code like this:

console.clear();
console.log("a");
setTimeout(function(){console.log("b");},1000);
console.log("c");
setTimeout(function(){console.log("d");},0);

A request comes in, and JS engine starts executing the code above step by step. The first two calls are sync calls. But when it comes to setTimeout method, it becomes an async execution. But JS immediately returns from it and continue executing, which is called Non-Blocking or Async. And it continues working on other etc.

The results of this execution is the following:

a c d b

So basically the second setTimeout got finished first and its callback function gets executed earlier than the first one and that makes sense.

We are talking about single-threaded application here. JS Engine keeps executing this and unless it finishes the first request, it won't go to second one. But the good thing is that it won't wait for blocking operations like setTimeout to resolve so it will be faster because it accepts the new incoming requests.

But my questions arises around the following items:

#1: If we are talking about a single-threaded application, then what mechanism processes setTimeouts while the JS engine accepts more requests and executes them? How does the single thread continue working on other requests? What works on setTimeout while other requests keep coming in and get executed.

#2: If these setTimeout functions get executed behind the scenes while more requests are coming in and being executed, what carries out the async executions behind the scenes? What is this thing that we talk about called the EventLoop?

#3: But shouldn't the whole method be put in the EventLoop so that the whole thing gets executed and the callback method gets called? This is what I understand when talking about callback functions:

function downloadFile(filePath, callback)
{
  blah.downloadFile(filePath);
  callback();
}

But in this case, how does the JS Engine know if it is an async function so that it can put the callback in the EventLoop? Perhaps something like theasync` keyword in C# or some sort of an attribute which indicates the method JS Engine will take on is an async method and should be treated accordingly.

#4: But an article says quite contrary to what I was guessing on how things might be working:

The Event Loop is a queue of callback functions. When an async function executes, the callback function is pushed into the queue. The JavaScript engine doesn't start processing the event loop until the code after an async function has executed.

#5: And there is this image here which might be helpful but the first explanation in the image is saying exactly the same thing mentioned in question number 4:

So my question here is to get some clarifications about the items listed above?

解决方案

1: If we are talking about a single-threaded application, then what processes setTimeouts while JS engine accepts more requests and executes them? Isn't that single thread will continue working on other requests? Then who is going to keep working on setTimeout while other requests keep coming and get executed.

There's only 1 thread in the node process that will actually execute your program's JavaScript. However, within node itself, there are actually several threads handling operation of the event loop mechanism, and this includes a pool of IO threads and a handful of others. The key is the number of these threads does not correspond to the number of concurrent connections being handled like they would in a thread-per-connection concurrency model.

Now about "executing setTimeouts", when you invoke setTimeout, all node does is basically update a data structure of functions to be executed at a time in the future. It basically has a bunch of queues of stuff that needs doing and every "tick" of the event loop it selects one, removes it from the queue, and runs it.

A key thing to understand is that node relies on the OS for most of the heavy lifting. So incoming network requests are actually tracked by the OS itself and when node is ready to handle one it just uses a system call to ask the OS for a network request with data ready to be processed. So much of the IO "work" node does is either "Hey OS, got a network connection with data ready to read?" or "Hey OS, any of my outstanding filesystem calls have data ready?". Based upon its internal algorithm and event loop engine design, node will select one "tick" of JavaScript to execute, run it, then repeat the process all over again. That's what is meant by the event loop. Node is basically at all times determining "what's the next little bit of JavaScript I should run?", then running it. This factors in which IO the OS has completed, and things that have been queued up in JavaScript via calls to setTimeout or process.nextTick.

2: If these setTimeout will get executed behind the scenes while more requests are coming and in and being executed, the thing carry out the async executions behind the scenes is that the one we are talking about EventLoop?

No JavaScript gets executed behind the scenes. All the JavaScript in your program runs front and center, one at a time. What happens behind the scenes is the OS handles IO and node waits for that to be ready and node manages its queue of javascript waiting to execute.

3: How can JS Engine know if it is an async function so that it can put it in the EventLoop?

There is a fixed set of functions in node core that are async because they make system calls and node knows which these are because they have to call the OS or C++. Basically all network and filesystem IO as well as child process interactions will be asynchronous and the ONLY way JavaScript can get node to run something asynchronously is by invoking one of the async functions provided by the node core library. Even if you are using an npm package that defines it's own API, in order to yield the event loop, eventually that npm package's code will call one of node core's async functions and that's when node knows the tick is complete and it can start the event loop algorithm again.

4 The Event Loop is a queue of callback functions. When an async function executes, the callback function is pushed into the queue. The JavaScript engine doesn't start processing the event loop until the code after an async function has executed.

Yes, this is true, but it's misleading. The key thing is the normal pattern is:

//Let's say this code is running in tick 1
fs.readFile("/home/barney/colors.txt", function (error, data) {
  //The code inside this callback function will absolutely NOT run in tick 1
  //It will run in some tick >= 2
});
//This code will absolutely also run in tick 1
//HOWEVER, typically there's not much else to do here,
//so at some point soon after queueing up some async IO, this tick
//will have nothing useful to do so it will just end because the IO result
//is necessary before anything useful can be done

So yes, you could totally block the event loop by just counting Fibonacci numbers synchronously all in memory all in the same tick, and yes that would totally freeze up your program. It's cooperative concurrency. Every tick of JavaScript must yield the event loop within some reasonable amount of time or the overall architecture fails.

这篇关于了解事件循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆