如何使用JavaScript';s的单线程模型可以处理耗时的任务吗?

如何使用JavaScript';s的单线程模型可以处理耗时的任务吗?,javascript,node.js,single-threaded,Javascript,Node.js,Single Threaded,这个问题与JavaScript的sinlge线程模型有关。我理解javascript本质上是非块的,因为它能够向异步事件队列添加回调。但是,如果回调函数实际上需要很长时间才能完成,那么JavaScript会不会在这段时间内阻塞其他所有内容,因为它是单线程的?nodejs如何处理这样的问题?对于前端开发人员来说,这是一个不可避免的问题吗?我问这个问题是因为我已经读到,保持函数任务尽可能小通常是一个很好的实践。这真的是因为javascript中的长任务实际上会阻止其他任务吗?您的问题非常大,所以我将

这个问题与JavaScript的sinlge线程模型有关。我理解javascript本质上是非块的,因为它能够向异步事件队列添加回调。但是,如果回调函数实际上需要很长时间才能完成,那么JavaScript会不会在这段时间内阻塞其他所有内容,因为它是单线程的?nodejs如何处理这样的问题?对于前端开发人员来说,这是一个不可避免的问题吗?我问这个问题是因为我已经读到,保持函数任务尽可能小通常是一个很好的实践。这真的是因为javascript中的长任务实际上会阻止其他任务吗?

您的问题非常大,所以我将只关注其中一部分

如果回调函数实际上需要很长时间才能完成,那么JavaScript会不会因为它是单线程的而在这段时间内阻塞其他所有内容?(…)这真的是因为javascript中的长任务实际上会阻止其他任务吗

非阻塞是一件美好的事情XD

最佳做法包括:

  • 将每个功能制动到其最小功能形式
  • Keep CallBacks Asynchronouss,是一篇关于回调使用的优秀文章
  • 避免堆叠操作(如嵌套循环)
  • 使用setTimeout()来阻止潜在的阻塞代码
  • 还有很多其他的东西,就是无阻塞的金本位,所以值得一看
--

--

setTimeout()是无阻塞代码中最重要的函数之一

假设你做了一个时钟函数,它看起来像这样:

function setTime() {
    var date=new Date();
    time = date.getTime()
    document.getElementById('id').innerHTML = time;

}
while(true){setTime();}
这很有问题,因为这段代码将愉快地循环它自己,直到时间结束。不会调用任何其他函数。你想停止操作,这样其他东西就可以运行了

function startTime() {
    var date=new Date();
    time = date.getTime()
    document.getElementById('id').innerHTML = time;
    setTimeout(startTime(),1000);
}
'setTimeout();'停止循环并每1秒执行一次。无限循环是一个极端的例子。点是“setTimeout();”擅长将大型运营链制动为小型运营链,使一切都更易于管理

但是,如果回调函数实际上需要很长时间才能完成,那么JavaScript会不会在这段时间内阻塞其他所有内容,因为它是单线程的

nodejs如何处理这样的问题

Node.js不处理任何内容。如何处理并发性取决于您和您的应用程序。现在,Node.js确实有一些工具可供您使用。您首先要了解的是Node.js基本上是V8(JavaScript引擎),在JavaScript和本机代码之间有一个轻量级的库。虽然JavaScript代码本质上是单线程的,但是本机代码可以并且确实创建线程来处理您的工作

例如,当您要求Node.js从磁盘加载文件时,您的请求将传递到使用线程池的本机代码,并且您的数据将从磁盘加载。一旦发出请求,JavaScript代码将继续运行。这就是Node.js上下文中“非阻塞”的含义。加载磁盘上的文件后,本机代码将其传递到Node.js JavaScript库,然后该库使用适当的参数执行回调。在后台工作进行期间,您的代码继续运行,但是当您的回调处理该数据时,其他JavaScript代码确实被阻止运行

此体系结构允许您获得多线程代码的许多好处,而无需实际编写任何多线程代码,从而保持应用程序的直观性

我问这个问题是因为我已经读到,保持函数任务尽可能小通常是一个很好的实践。这真的是因为javascript中的长任务实际上会阻止其他任务吗

我的理念是永远使用你需要的东西。确实,如果一个请求进入到您的应用程序,并且您有大量的JavaScript数据处理被阻塞,那么在此期间将不会处理其他请求。但是请记住,如果您正在做这类工作,那么您很可能会受到CPU的限制,并且做双倍的工作将导致两个请求都需要更长的时间

实际上,大多数web应用程序都是IO绑定的。他们洗牌数据库中的数据,重新格式化,然后通过网络发送出去。与应用程序等待上游数据源回音的时间相比,它们处理数据的部分实际上并不那么耗时。Node.js正是在这些应用程序中大放异彩


最后,请记住,始终可以生成子进程以更好地分配负载。如果您的应用程序很少使用CPU绑定JavaScript完成99%的工作负载,并且有一个包含许多CPU和/或内核的盒子,那么可以将负载分成几个进程。

这一点相当广泛;你的代码会做什么如此耗时的事情?“我知道javascript本质上是非块的”-不,不是。这是node.js的一些API函数的设计特点。JavaScript本身在每次函数调用时都会阻塞。它不会冻结浏览器,而是会冻结浏览器。每个JavaScript函数调用都会这样做。它们中的大多数发生得太快,以至于您无法注意到,因此在您执行一些时间密集型操作之前,这不是一个问题。不,阻塞是任何单线程环境的一个限制。答案很简单:节点不是单线程的。此外,节点将时间密集型任务卸载到底层操作系统,该操作系统为涉及等待的操作(如网络和磁盘IO)提供异步功能。