我已经越来越多地进入node.js体系结构的内部,我看到的一个术语是"tick",如"事件循环的下一个tick"或函数nextTick().
我没有看到的是对什么是"滴答"的确切定义.基于各种文章(例如这篇文章),我已经能够将一个概念拼凑在一起,但我不确定它是多么准确.
我能获得node.js事件循环滴答的精确详细描述吗?
我想知道以下javascript环境如何作为系统互连.
我们可以将此限制为浏览器环境,因为节点已在另一篇文章中介绍(此处)
Javascript是单线程的,因此只有一个callstack.
Javascript环境只提供一些真正异步的函数.这些可能包括setTimeout(),setInterval()和I/O函数.
console.log(‘Sync code started…’);
setTimeout(function asyncLog() {
console.log(‘Async function has completed’)
}, 2000);
console.log(‘Sync code finished…')
Run Code Online (Sandbox Code Playgroud)
(如果我错了,请纠正步骤)
如果有人可以概述async函数(例如setTimeout)从第一次访问callstack到回调到callstack的时间和位置的步骤的概述,则不需要逐个回答这些步骤.
javascript asynchronous event-loop event-queue single-threaded
语法的哪一部分提供了此函数应该在其他线程中运行并且是非阻塞的信息?
让我们考虑node.js中的简单异步I/O.
var fs = require('fs');
var path = process.argv[2];
fs.readFile(path, 'utf8', function(err,data) {
var lines = data.split('\n');
console.log(lines.length-1);
});
Run Code Online (Sandbox Code Playgroud)
究竟是什么让它在背景中发生?任何人都可以准确地解释它或粘贴一些好资源的链接?我看到的每个地方都有关于回调是什么的大量信息,但没有人解释为什么它实际上是这样的.
这不是关于node.js的具体问题,而是关于每种编程语言中回调的一般概念.
编辑:
可能我提供的例子并不是最好的.所以我们不要考虑这个node.js代码片段.我一般都在问 - 当遇到回调函数时,程序是如何继续执行的.什么是语法使回调概念成为非阻塞概念?
提前致谢!
Node.JS最大的优点是它具有非阻塞性.它是单线程的,因此不需要为每个新的传入连接生成一个新线程.
在事件循环(实际上是单线程)后面,有一个"非阻塞工作者".这个东西不再是单线程了,所以(据我所知)它可以为每个任务生成一个新线程.
也许我误解了一些东西,但究竟哪里有优势.如果要处理的任务很多,那么非阻塞工作会不会变成阻塞工作者?
谢谢Christian
let a = true;
setTimeout(() => {a = false}, 1000)
while(a){console.log(a)}
Run Code Online (Sandbox Code Playgroud) 我对Node js的架构和性能有疑问.
我已经完成了一些关于这个主题的阅读(包括Stack Overflow),我还有几个问题.我想做两件事:
Node具有单线程,异步事件处理架构
单线程 - 有一个事件线程可以调度异步工作(结果通常是I/O但可以是计算)并执行回调执行(即处理异步工作结果).
事件线程在无限的"事件循环"中运行,执行上述2个作业; a)通过调度异步工作来处理请求,以及b)注意先前的异步工作结果已准备好并执行回调以处理结果.
这里的常见类比是餐厅订单接收者:活动线程是一个超级快速的服务员,从餐厅接受订单(服务请求)并将订单发送到厨房准备(发送异步工作),但也注意到当食物准备就绪(异步结果)并将其送回表格(回调执行).
服务员不做任何食物; 他的工作是尽快从餐厅到厨房来回走动.如果他陷入餐厅的订单陷入困境,或者如果他被迫回到厨房准备其中一餐,系统就变得效率低下并且系统吞吐量受损.
异步 由请求(例如Web请求)产生的异步工作流在逻辑上是一个链:例如
FIRST [ASYNC: read a file, figure out what to get from the database] THEN
[ASYNC: query the database] THEN
[format and return the result].
Run Code Online (Sandbox Code Playgroud)
上面标有"ASYNC"的作品是"厨房工作","FIRST []"和"THEN []"代表服务员开始回调的参与.
像这样的链以3种常见方式以编程方式表示:
嵌套函数/回调
用.then()链接的承诺
async()异步结果的异步方法.
所有这些编码方法都非常相同,尽管asynch/await似乎是最干净的,并且使得异步编码的推理更容易.
问题
我的问题涉及使用OS支持的异步操作,实际执行异步工作的人,以及这种体系结构比"按每个请求生成一个线程"(即多个cooks)体系结构更高效的方式:
通过使用跨平台异步库libuv设计节点库是异步的,对吗?这里的想法是libuv为节点(在所有平台上)提供一致的异步I/O接口,但随后使用平台相关的异步I/O操作吗?在I/O请求"一直向下"到OS支持的异步操作的情况下,谁正在"做工作"等待I/O返回并触发节点?它是内核,使用内核线程吗?如果不是,谁?无论如何,这个实体可以处理多少个请求?
我已经读过libuv也在内部使用了一个线程池(通常是pthreads,每个核心一个?).这是为了"包装"不像"async"那样"完全向下"的操作,这样一个线程就可以用来等待同步操作了,所以libuv可以提供一个异步API吗?
关于性能,用于解释类似节点的体系结构可以提供的性能提升的通常说明是:画出(可能更慢和更胖)线程每请求方法 - 产生的延迟,CPU和内存开销一堆线程只是坐在等待I/O完成(即使他们没有忙碌等待)然后将它们拆除,节点很大程度上让它消失了,因为它使用了一个长期存在的事件线程来将异步I/O发送到OS /内核,对吗?但是在一天结束的时候,SOMETHING正在睡眠互联网并在I/O准备就绪时被唤醒...是否认为内核比用户线程更有效?最后,请问由libuv的线程池处理的情况怎么样...这似乎与每个请求线程的方法类似,除了使用池的效率(避免启动和拆除),但是在这种情况下,当有很多请求并且池有积压时会发生什么?...延迟增加,现在你做的比每个请求的线程更糟,对吧?
我正在为我们的新后端项目考虑一些框架/编程方法。它涉及一个 BackendForFrontend 实现,它聚合下游服务。为简单起见,这些是它经过的步骤:
事件驱动编程如何比“常规”线程每请求处理更好?一些网站试图解释,通常归结为这样的:
第二种解决方案是非阻塞调用。调用者没有等待答案,而是继续执行,但提供了一个回调,一旦数据到达就会执行。
我不明白的是:我们需要一个线程/处理程序来等待这些数据,对吗?很高兴事件处理程序可以继续,但我们仍然需要(在本例中)每个请求的线程/处理程序等待每个下游请求,对吗?
考虑这个例子:下游请求需要 n 秒才能返回。在这 n 秒内,r 个请求进来。在 thread-per-request 中,我们需要 r 个线程:每个请求一个。经过 n 秒后,第一个线程完成处理并可用于新请求。
在实现事件驱动设计时,我们需要 r+1 个线程:一个事件循环和 r 个处理程序。每个处理程序接受一个请求,执行它,并在完成后调用回调。
那么这如何改进呢?
我正在努力理解异步性的概念。以下关于异步操作的描述大致正确吗?
\n如果一段代码需要很长时间才能完成,则可能会出现问题。这是因为 i) 它会阻止下面的代码运行,并且在后台加载硬代码时运行它可能会很好。ii) 事实上,JS 可能会在硬代码\xe2\x80\x99s 完成之前尝试执行下面的代码。如果下面的代码依赖于硬代码,那么 \xe2\x80\x99 就会出现问题。
\n一个解决方案是:如果一个操作需要很长时间才能完成,您希望在处理原始线程的同时在单独的线程中处理它。只需确保主线程不引用异步操作返回的内容即可。JS 使用事件队列来解决这个问题。异步操作在主线程之后执行的事件队列中执行。
\n但即使是事件队列也可能遇到与主线程相同的问题。如果位于 fetch2 之上的 fetch1 需要很长时间才能返回 Promise,而 fetch2 则不会\xe2\x80\x99t,则 JS 可能会在执行 fetch1 之前开始执行 fetch2。这是Promise.all很有用的地方,因为在 fetch1 和 fetch2\xe2\x80\x99s 承诺都得到解决之前,它不会继续执行异步操作中的下一步。
另请注意, I\xe2\x80\x99ve read when chaining .then,这算作一个异步操作,因此我们始终可以保证后续操作.then仅在.then之前执行|解决其承诺时才会执行。
我正在开发NodeJS应用程序。有一个特定的RESTful API(GET),当用户触发该API时,它要求服务器执行大约10到20个网络操作才能从不同来源获取信息。所有这些网络操作都是异步回调,一旦它们全部完成,结果将由nodejs应用程序合并并发送回客户端。所有这些操作都是通过async.map函数并行启动的。
我只想了解一下,因为nodejs是单线程的,并且不使用多核计算机(至少不是没有集群),所以当节点有许多回调要处理时,节点如何扩展?回调的实际处理是取决于节点的单线程是否空闲,还是与主线程并行处理回调?
我问的原因是,我看到我的20个回调的性能从第一个回调降到了最后一个。例如,第一个网络操作(从10到20)需要141毫秒才能完成,而最后一个网络操作则需要约4秒钟(以从执行该功能到函数的回调返回值或一个错误)。它们都是相同的网络操作,因此命中相同的数据源,因此数据源不是瓶颈。我知道一个事实,即数据源响应单个请求所花费的时间不超过200ms。
我找到了这个线程,所以在我看来,一个线程需要处理所有回调和即将出现的新请求。
所以我的问题是,对于将触发许多回调的操作,优化其性能的最佳实践是什么?
主要看 FS api,对于大多数功能来说,似乎有三种风格可供选择:
异步是使用系统资源的更好方法,但是,如果我已经在异步函数中并且正在等待每个调用,那么这与仅使用同步调用之间应该没有任何区别,对吗?对我来说,它就像一个内置的等待语句。
我不知道异步是如何在 js/node 中实现的。如果我一开始就在异步函数中,那么使用异步函数有什么好处吗?(不包括并行运行异步任务时的场景)
我一直在思考像 React 这样的代码和库,它们可以自动对发生的事件做出反应,并且想知道所有这些是如何在 C++ 和机器代码的较低级别实现的。
我似乎无法想出任何其他方式可以使用 if not with while loop 在另一个线程上运行来实现诸如事件侦听器之类的东西。
那么这一切都在幕后吗?只是 while 一直循环下去?例如,RethinkDB 将自己宣传为具有repubsub库的“实时数据库” 。“订阅”方法是否只是在后台使用 while 循环实现的?我似乎无法找到任何相关信息。
像,插座之类的,也是。当计算机在端口上“侦听”套接字连接时,该计算机是否正在运行类似以下内容:
while(1) {
if (connectionFound) {
return True;
}
}
Run Code Online (Sandbox Code Playgroud)
或者有什么我想念的吗?
NodeJS新手.通过承诺教程('promise-it-wont-hurt')我有以下脚本:
var Q = require('q');
var deferred = Q.defer();
deffered.resolve('SECOND');
deffered.promise.then(console.log);
console.log('FIRST');
Run Code Online (Sandbox Code Playgroud)
输出:
FIRST
SECOND
Run Code Online (Sandbox Code Playgroud)
我不明白,我会想到,既然已经解决了,那么我应该先看到第二个.
他们解释说,这是因为"Promise在事件循环的同一转弯时触发".我不明白这意味着什么......
我是 JavaScript 新手,想知道“JS”如何处理异步操作。我开始知道它是在“事件循环”和“事件队列”的帮助下完成的,但我不知道其中的区别。有人可以帮我吗。
的一个例子asynchronous operations可以是:
function alpha(){
setTimeout(() => alert("hi"), 3000);
};
alpha();Run Code Online (Sandbox Code Playgroud)
javascript ×11
node.js ×8
asynchronous ×4
callback ×2
event-loop ×2
loops ×2
async-await ×1
css ×1
ecmascript-6 ×1
event-driven ×1
event-queue ×1
events ×1
html ×1
nonblocking ×1
q ×1
reactjs ×1
rethinkdb ×1
settimeout ×1
webserver ×1