gpt4 book ai didi

javascript - Node JS SetTimeOut回调

转载 作者:太空宇宙 更新时间:2023-11-04 03:02:41 25 4
gpt4 key购买 nike

我一直在newboston频道(链接https://www.youtube.com/watch?v=KsjrN-T3ZCs)上进行节点JS培训。下面给出了有关如何提供更好性能的示例



function placeAnOrder(orderNumber) {
console.log("Order placed", orderNumber);
cookAndDeliver(function () {
console.log("Delivered order", orderNumber);
});
};


function cookAndDeliver(callback){
setTimeout(callback, 5000);
};


placeAnOrder(1);
placeAnOrder(11);
placeAnOrder(111);
placeAnOrder(1111);
placeAnOrder(11111);





如果您运行示例,您会注意到首先所有订单都一次下达,这是正常的,然后所有订单也都交付了一次,这是不正常的,因为每个调用已经存在5秒的超时约束。

视频给出的解释是,回调没有阻碍,并且代码将不受干扰地执行,对此我表示同意,我不明白的是,为什么节点不遵守超时值?

我的猜测是,由于它以异步模式运行,那么这意味着将有一个单独的线程来处理每个调用,我的假设正确吗?

最佳答案

这是事件的顺序:


首先拨打placeAnOrder()
它调用cookAndDeliver()
它调用setTimeout()
setTimeout()将计时器事件从现在开始安排5秒钟,并立即返回。
呼叫第二个placeAnOrder()
它调用cookAndDeliver()
它调用setTimeout()
setTimeout()将计时器事件从现在开始安排5秒钟,并立即返回。
呼叫第二个placeAnOrder()
它调用cookAndDeliver()
它调用setTimeout()
setTimeout()将计时器事件从现在开始安排5秒钟,并立即返回。
再重复两次,总共5个计时器将从现在开始大约5秒
JavaScript解释器将控制权返回到事件循环,因为它暂时不再需要做任何事情
然后从现在开始大约5秒钟,Javascript的内部将第一个计时器事件放置到事件队列中
如果此时Java解释器没有执行任何操作,则它将触发该事件并调用与该计时器事件关联的回调。
该回调执行。
当该回调执行时,事件队列中还有另一个计时器事件,并且JS解释器调用其回调进行处理。
完成回调之后,从事件队列中一次提取一个下一个3个计时器事件,并执行其回调。


这里没有Javascript线程。 node.js中的Javascript是单线程的。一切都通过中央事件队列运行。 Javascript的内部可能使用线程来执行异步操作(例如,异步文件I / O确实使用其实现内部的线程,但不用于运行Javascript)。完成这些线程后,它们会将一个事件放入事件队列中,并且当单个node.js Javascript线程完成执行其正在执行的操作后,它将从事件队列中获取下一个事件并执行与之关联的回调。


  我的猜测是,由于它以异步模式运行,那么这意味着将有一个单独的线程来处理每个调用,我的假设正确吗?


不,那是不正确的。 setTimeout()将计时器事件安排在将来的某个时间。没有与计时器事件关联的Javascript线程。可能有一个系统线程来管理所有计时器事件(也可能没有)(这是特定于实现的,实际上并不重要-也可能是,每当Javascript返回事件循环时,它只会检查其时间是否到了触发下一个计时器事件)。当计时器触发的时间到了时,会将一个事件插入到Javascript事件队列中。然后,JS解释器会在下次处理时从事件循环中拾取该事件,并正在寻找下一个要处理的事件。


  下面给出了一个有关如何提高节点性能的示例。


我认为他们试图展示的是由于node.js异步事件驱动的设计,异步事件(如计时器)没有多个线程。这样,当同时进行大量异步操作时,它就可以更好地扩展,因为它的模型比每个计时器都有一个系统线程的模型更有效。


  如果您运行示例,您会注意到首先所有订单都一次下达,这是正常的,然后所有订单也一次交付,这是不正常的,因为每个调用已经存在5秒的超时约束。


该代码实际上在一行中运行5个setTimeout()调用,所有调用都将计时器设置为从现在起5秒触发。 setTimeout()是非阻塞的。这意味着它将计时器从现在开始调度5秒,然后立即进入下一行代码,该代码还将调度计时器从现在开始进行5秒。因此,您最终将安排5个计时器,从现在开始约5秒钟(从一个setTimeout()调用到下一个调用之间的执行时间可能只有几毫秒的变化。最终结果是所有5个计时器将在5秒钟内触发)他们将按照预定的顺序开火。


  视频中给出的解释是,回调没有阻碍,代码将不受干扰地执行,我同意这一点,但我没有得到的是为什么节点不遵守超时值?


因为setTimeout()是非阻塞的(就像node.js中的所有异步操作一样)。它将计时器安排在将来的某个时间,然后立即返回(这是非阻塞部分)。无需等待5秒钟即可返回。它立即返回并执行接下来的代码。然后从现在起5秒钟(当JS解释器无事可做时),将调用计时器回调。

关于javascript - Node JS SetTimeOut回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50594685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com