阻止代码是否总是使用返回语句和非阻塞代码总是使用callback?

在初学者教程中,Node的非阻塞性质通常通过显示阻塞的例子(使用return语句)和非阻塞的Node例子(使用callback)来演示。 有关示例,请参阅此处 。

我应该把它作为一个“气味”,使用return在我的节点应用程序中创build阻止代码,并find一种方法来使用callback重做它?

TL; DR:如果代码可能需要“很长”的时间,那么使用callback来处理它可能会更清洁/更高效。

这不是关于return / not-return,而是关于代码实际上做了什么。

示例函数不阻塞, 因为有一个返回,因为db.query需要一个任意数量的时间,所以它阻塞。 如果您想在此期间做其他事情,马上回来,并在callback中做结果处理。

不pipe你是否应该依赖于实际发生了什么,还有什么可能会受到或依赖于传递给callback(或返回)的数据等等。

阻塞调用通常会返回一些内容,因为返回是在调用引起的“操作”之后发生的,所以它可以返回有关操作成功或失败以及操作产生的任何数据的信息。 这也适用于本身不阻塞的调用,但不执行I / O,所以不需要callback。

非阻塞调用(例如读取文件的函数)不会倾向于使用返回值,因为它们在执行任何重要操作之前通常会返回。 相反,他们调用callback并发送任何数据,或者可能是错误消息。

使用非阻塞调用的主要动机是您正在等待某个外部进程或设备返回,因此您释放对线程的控制以允许其他操作在“等待”时运行。

因为使用callback的非阻塞/asynchronous代码更难以编写,读取和维护,所以应该避免使用非阻塞代码,除非它会影响应用程序的性能和可伸缩性,或者API所需的位置您正在使用。

考虑这个相对愚蠢的例子:

  function add(a,b,cb) { cb(a+b); } console.log('2+2 is', add(2,2)); // -> 4 function add(a,b) { return a+b; } add(2,2,function(sum) { console.log('2+2 is', sum); }); // -> 4 

第一个是在眼睛上更容易一点。

许多节点API具有asynchronous版本,但没有同步版本。 当使用这些API时,显然你需要使你的代码asynchronous。

在有select的情况下(比如在读文件的时候)问自己:“阻塞的呼叫是否会让terminal用户等待不合理的时间?”。 在应用程序启动期间,答案通常是“否”,因为代码只运行一次,最终用户没有机会触摸服务器。 但是,如果您正在响应Web请求,那么使所有用户等待出站API调用或磁盘读取将使所有用户的站点变慢,而非阻塞调用则允许节点继续处理新的请求,直到数据为止要求回来。