简体   繁体   English

哪些函数应该是异步的(置于Node.js中)?

[英]What functions should be asynchronous (put inside Node.js promises)?

My knowledge of the subject is quite low in general, so please bear with me. 我对这个问题的了解总体上很低,所以请耐心等待。

I understand that functions that might require an extra delay, like database read/writes, file reads, etc. should be run asynchronously, so as to not block. 我知道可能需要额外延迟的函数,如数据库读/写,文件读取等,应该异步运行,以免阻塞。

What hasn't really been answered after my searches is: 我的搜索后没有真正回答的是:

Should something like a simple for-loop be run asynchronously? 应该像简单的for循环那样异步运行吗? It could be something as simple as: 它可能很简单:

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

Since something like this could take a few milliseconds, should it be put inside a Node.js promise? 因为这样的事情可能需要几毫秒,它应该放在Node.js承诺中吗?

Am I correct to assume that if I don't, then yes there will be blocking, albeit for just a few milliseconds? 我是否正确地假设如果我不这样做,那么肯定会有阻塞,虽然只有几毫秒?

I'm not sure if I understand you correctly, but I don't think that will work as you expect. 我不确定我是否理解正确,但我认为这不会像你期望的那样有效。 "Wrapping" that function inside a future will make the call asynchronous but not the function itself. 在未来“包装”该函数将使调用异步但不是函数本身。

Suppose the following scenario: 假设以下场景:

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

if a() is synchronous f2() will only be executed after a() finishes (ie your for loop). 如果a()是同步的,则f2()只会在a()完成后执行(即你的for循环)。 Now if a() is asynchronous this means that f2() will be executed right away, so it does not block execution. 现在如果a()是异步的,这意味着f2()将立即执行,因此它不会阻止执行。

But as NodeJS is single-threaded and all code is executed in a loop, whenever that for loop gets executed it will be run from start to finish (from iteration 0 to 9999999) without pauses, so it will block other operations during that time. 但由于NodeJS是单线程的并且所有代码都是在循环中执行的,因此无论何时执行for循环,它都将从开始到结束(从迭代0到9999999)运行而不会暂停,因此它将在此期间阻止其他操作。

So using promises you are only delaying when that code will block you app. 因此,使用promises只会在代码阻止你的app时延迟。

If that function only takes some milliseconds to complete that may not make a lot of difference. 如果该功能只需要几毫秒才能完成,这可能不会产生很大的不同。 But if it takes seconds or minutes for example, you would need to make sure that task gives back control to NodeJS from time to time using nextTick or using something like async.eachSeries . 但是,如果需要几秒或几分钟,您需要确保该任务使用nextTick或使用async.eachSeries之类的东西不时地向nextTick返回控制

This article explains this is some detail. 本文解释了这一些细节。

Since something like this could take a few milliseconds, should it be put inside a Node.js promise? 因为这样的事情可能需要几毫秒,它应该放在Node.js承诺中吗?

Ideally, yes. 理想情况下,是的。 Node, or rather the V8 engine in general, is designed for high throughput/scalability therefore anything that will effectively block execution should be run asynchronously. 节点,或者更确切地说是V8引擎,是为高吞吐量/可扩展性而设计的,因此任何有效阻止执行的都应该异步运行。

There is a difference between "being run asynchronously" and "being written for asynchronous-ity". “异步运行”和“异步运行”之间存在差异。

Like you mentioned, NodeJS is blocking when it runs a loop. 就像你提到的那样,NodeJS在运行循环时会阻塞。 That means nothing else will run on the CPU. 这意味着没有其他任何东西可以在CPU上运行。 It does not matter where that function is called, it will use all the CPU cycles until it finishes. 调用该函数的位置并不重要,它将使用所有CPU周期直到完成。

If you run it asynchronously, via a Promise or the async library, whenever the for-loop runs, it will run forever until it is done. 如果你通过Promise或async库异步运行它,那么每当for-loop运行时,它将一直运行直到完成。 Nothing else will run at this time, it will block all other actions. 此时没有其他任何东西会运行,它会阻止所有其他操作。 If you write it for asynchronous-ity, you would break down the loop into smaller chunks, that would be run asynchronously in series or parallel, each chunk being small enough to not seriously impact other things that are happening. 如果你为异步编写它,你可以将循环分解为更小的块,这些块将以串行或并行的方式异步运行,每个块都足够小,不会严重影响正在发生的其他事情。

Is a few milliseconds too much? 几毫秒太多了? Depends on your app. 取决于您的应用程序。 The thing is, the processing will have to happen sometime, so there is no point in breaking it down too much. 问题是,该处理要发生的某个时候,所以在它分解太多没有意义的。 Just be aware that a loop (and some other constructs, like Array.forEach ) are blocking your other events from processing, do your best to avoid problems, and test your app the best you can. 请注意,循环(以及其他一些构造,如Array.forEach )会阻止您处理其他事件,尽力避免出现问题,并尽可能地测试您的应用程序。

Nodejs is different from most other programming environments in that all users of a web app share the same thread. Nodejs与大多数其他编程环境的不同之处在于,Web应用程序的所有用户共享相同的线程。 That means if one user is requesting information from the database, you do not want all the other users to wait in line for the database request to be complete before processing, say some other user's request for a page load. 这意味着如果一个用户从数据库请求信息,您不希望所有其他用户在处理之前排队等待数据库请求完成,比如其他用户对页面加载的请求。 Hence, it is a good idea, as much as is possible, to free up the thread so Node can serve other user requests. 因此,尽可能地释放线程以便Node可以提供其他用户请求是一个好主意。

Now what does free up the thread mean? 现在释放线程的意思是什么? Essentially, the V8 engine (underpinning nodejs) executes commands in a step-by-step manner, as most programmers are used to. 从本质上讲,V8引擎(支持nodejs)以逐步的方式执行命令,正如大多数程序员习惯的那样。 However, it is possible that the execution thread reaches a point where it is waiting for input from another source. 但是,执行线程可能会到达等待来自其他源的输入的点。 If the function is written in an synchronous manner, the execution simply waits there until the input is received and then continues to process the rest of the program. 如果以同步方式写入函数,则执行只是在那里等待,直到接收到输入,然后继续处理程序的其余部分。 However, if the function is written in a non-blocking (asynchronous) manner, the thread is freed up to execute any other functions that are available (eg new requests from other users). 但是,如果函数是以非阻塞(异步)方式编写的,则释放线程以执行任何其他可用的函数(例如,来自其他用户的新请求)。 Writing your code in a non-blocking mode makes the execution much more efficient in a multi-user environment. 以非阻塞模式编写代码使得在多用户环境中执行更加高效。

Now for your specific issue, the question to ask is if you make the function, a(), asynchronous, would you be freeing up the execution thread? 现在针对您的具体问题,要问的问题是,如果您创建函数,a(),异步,您是否可以释放执行线程? The answer is NO. 答案是不。 This is because node is still executing the for loop and so no other functions can be executed at the same time and there is no point at which node execution is suspended waiting for another system to provide input. 这是因为节点仍在执行for循环,因此不能同时执行其他功能,并且没有任何点暂停执行,等待另一个系统提供输入。 So, no do not make your for loops asynchronous. 所以,不要让你的for循环异步。 It just adds complexity to your code and provides no value to the execution effectiveness. 它只会增加代码的复杂性,并且对执行效率没有任何价值。 Instead, just try to make sure the for loops are executed as efficiently as possible. 相反,只是尝试确保尽可能有效地执行for循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM