什么函数应该是asynchronous的(放在Node.js中)?

我对这个问题的了解一般都很低,所以请耐心等待。

我明白,可能需要额外延迟的function,如数据库读取/写入,文件读取等应该asynchronous运行,以免阻塞。

我的search后没有真正回答的是:

应该像一个简单的for循环asynchronous运行? 这可能是如下简单的事情:

function a() { var a = 0; for(i=0; i<10000000; i++) { a++; }; }; 

因为像这样的事情可能需要几毫秒,应该把它放在一个Node.js的承诺?

我是否正确地认为,如果我不这样做,那么会有阻塞,尽pipe只有几毫秒?

我不确定我是否正确理解你,但我不认为这会按你的预期工作。 在未来的“包装”function将使呼叫asynchronous,但不是function本身。

假设以下情况:

 f1(); a(); f2(); f3(); // (...) 

如果a()是同步的f2()只会在a()完成后执行(即for循环)。 现在如果a()是asynchronous的,这意味着f2()将被立即执行,所以它不会阻止执行。

但是由于NodeJS是单线程的,并且所有的代码都是在一个循环中执行的,所以无论何时执行for循环,它都将从头到尾(从0到9999999的迭代)不间断地运行,因此在此期间将阻止其他操作。

所以使用承诺,你只是拖延,当代码将阻止你的应用程序。

如果这个函数只需要几毫秒的时间来完成,那可能没有太大的区别。 但是,如果需要几秒或几分钟,则需要确保该任务不时地使用nextTick或使用诸如async.eachSeries之类的东西来控制NodeJS 。

这篇文章解释了这是一些细节。

因为像这样的事情可能需要几毫秒,应该把它放在一个Node.js的承诺?

理想的是,是的。 节点,或者说一般来说V8引擎是为高吞吐量/可伸缩性而devise的,因此任何有效阻止执行的东西都应该asynchronous运行。

“正在asynchronous运行”和“正在写asynchronous”是有区别的。

就像你刚才提到的那样,NodeJS在运行一个循环时会被阻塞。 这意味着没有别的将在CPU上运行。 这个函数被调用的地方并不重要,它将使用所有的CPU周期,直到完成。

如果通过Promise或asyncasync运行,则for-loop运行时,将永远运行,直到完成。 此时没有别的东西会运行,它会阻止所有其他的动作。 如果你为asynchronous编写它,你会把循环分解成更小的块,这些块将以串行或并行的方式asynchronous运行,每个块都足够小,不会严重影响正在发生的其他事情。

几毫秒太多了? 取决于你的应用程序。 事情是,处理不得不在某个时候发生,所以没有必要把它分解得太多。 只要注意一个循环(以及一些其他的构造,如Array.forEach )阻止了其他事件的处理,尽力避免出现问题,并尽可能地testing你的应用程序。

Nodejs与大多数其他编程环境的不同之处在于,Web应用程序的所有用户都共享相同的线程。 这意味着,如果一个用户正在从数据库请求信息,则不希望所有其他用户在处理之前等待数据库请求完成,并说明其他用户对页面加载的请求。 因此,尽可能释放线程是一个好主意,以便Node可以服务于其他用户请求。

现在释放线程是什么意思? 本质上,V8引擎(支撑nodejs)按照大多数程序员的习惯,逐步执行命令。 但是,执行线程有可能达到等待来自其他源的input的点。 如果函数是以同步方式写入的,那么执行只是等待直到接收到input,然后继续处理程序的其余部分。 但是,如果函数是以非阻塞(asynchronous)方式编写的,则线程将被释放以执行任何其他可用的函数(例如来自其他用户的新请求)。 以非阻塞模式编写代码使得在多用户环境中执行效率更高。

现在针对你的具体问题,要问的问题是如果你做了这个函数,一个(),asynchronous的,你会释放执行线程吗? 答案是不。 这是因为节点仍在执行for循环,所以没有其他function可以同时执行,也没有指出哪个节点执行被挂起,等待另一个系统提供input。 所以,不要让你的for循环asynchronous。 这只会增加代码的复杂性,并不会提高执行效率。 相反,只要确保for循环尽可能有效地执行。