阻塞代码是否总是使用 return 语句,而非阻塞代码总是使用回调?
在初学者教程中,Node 的非阻塞性质通常通过展示阻塞示例(使用 return 语句)和非阻塞 Node 示例(使用回调)来演示。有关示例,请参阅此处。
我是否应该将其视为使用 return
在我的 Node 应用程序中创建阻塞代码的“气味”,并找到一种使用回调重做它的方法?
In beginner tutorials, Node's non-blocking nature is usually demonstrated by showing a blocking example (using a return
statement) and the non-blocking Node example (using callbacks). For an example, see here.
Should I take it as a "smell" that using return
creates blocking code in my Node app, and find a way to redo it using callbacks?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
TL;DR:如果代码可能需要“很长”的时间,那么使用回调处理它可能会更干净/更有效。
这与返回/不返回无关,而是与代码实际执行的操作有关。
示例函数不会因为有返回而阻塞,而是因为 db.query 需要任意时间而阻塞。如果你想在这段时间做其他事情,就立即返回,并在回调中进行结果处理。
您是否应该取决于实际发生的情况,还有什么可能受传递给回调(或返回)的数据影响或依赖于传递给回调(或返回)的数据,等等。
TL;DR: if code may take a "long" time, it may be cleaner/more efficient to handle it with a callback.
It's not about return/not-return, it's about what the code actually does.
The example function doesn't block because there's a return, it blocks because
db.query
takes an arbitrary amount of time. If you want to do other things during that time, return right away, and do the result processing in the callback.Whether or not you should depends on what's actually going on, what else may be affected by, or depend on, the data passed to the callback (or returned), and so on.
阻塞调用通常会返回一些内容,因为返回发生在调用引起的“操作”之后,因此它可以返回有关操作成功或失败的信息以及该操作生成的任何数据。这也适用于本身不阻塞但不执行 I/O 的调用,因此不需要回调。
非阻塞调用(例如对读取文件的函数的调用)往往不会使用返回值,因为它们通常在执行任何重要操作之前返回。相反,他们调用回调并向其发送生成的任何数据,或者可能是错误消息。
Blocking calls typically return something because the return happens after the "action" caused by the call, so it can return information about the success or failure of the action, and any data produced by the action. This applies also to calls that don't block per se, but don't do i/o, so the callback isn't needed.
Non-blocking calls, such as one to a function that reads a file, don't tend to make use of the return value because they typically return before they do anything of significance. Instead, they call the callback and send it whatever data was produced, or possibly an error message.
使用非阻塞调用背后的主要动机是您正在等待某些外部进程或设备返回,因此您释放对线程的控制以允许其他操作“在等待时”运行。
由于使用回调的非阻塞/异步代码更难以编写、读取和维护,因此您应该避免使用非阻塞代码,除非它会影响应用程序的性能和可扩展性,或者 API 需要它你正在使用。
考虑这个相对愚蠢的例子:
第一个例子相对容易一些。
许多节点 API 有异步版本,但没有同步版本。使用这些 API 时,很明显您需要使代码异步。
如果您有选择(例如读取文件时),请问问自己:“阻塞调用会让最终用户等待不合理的时间吗?”。在应用程序启动期间,答案通常是“否”,因为该代码仅运行一次,并且最终用户没有机会接触服务器。但是,如果您正在响应 Web 请求,那么让所有用户等待出站 API 调用或磁盘读取将会减慢所有用户的站点速度,而非阻塞调用允许节点继续处理新请求,直到您收到数据为止。请求回来。
The main motivation behind a using a non-blocking call is that you are waiting for some external process or device to return, so you release control of the thread to allow other operations to run "while you wait".
Because non-blocking/asynchronous code using callbacks is more difficult to write, read, and maintain you should avoid non-blocking code except where it will make a difference in the performance and scalability of your application, or where it is required by an API you are using.
Consider this relatively silly example:
The first one is a fair bit easier on the eyes.
Many node APIs have an asynchronous version but no syncronous version. When using those APIs it will be obvious that you need to make your code asynchronous.
In cases where you have a choice (as when reading a file) ask yourself: "Will a blocking call make the end-user wait for an unreasonable amount of time?". During application startup the answer is generally "no" because that code only runs once and the end users haven't had the chance to touch the server. However, if you are responding to a web request then making all users wait for an outbound API call or disk read will slow down the site for all the users, whereas a non-blocking call allows node to continue processing new requests until the data you requested comes back.