2011-10-25 196 views

回答

4

TL; DR:如果代码可以采取“长”时,它可以清洁剂/更高效与一个回调来处理它。

这不是回报/不回报,这是什么代码实际上做。

示例函数不会阻止,因为有返回,因为db.query需要一段任意的时间,所以它会被阻止。如果您想在此期间做其他事情,请立即返回,并在回调中执行结果处理。

是否应该取决于实际发生了什么,还有其他什么可能会影响或依赖传递给回调(或返回)的数据,等等。

1

阻塞调用通常返回的东西,因为所造成的呼叫“动作”后恢复情况,所以它可以返回有关成功或行动的失败,由动作产生的任何数据信息。这也适用于本身不阻止的调用,但不执行I/O,因此不需要回调。

非阻塞调用,如一个读取文件的功能,不倾向于使用返回值的,因为他们他们做任何有意义的东西之前,通常返回。相反,他们会调用回调函数并将其发送给任何数据,或者可能是错误消息。

0

后面使用非阻塞调用,你正在等待一些外部进程或设备返回,让你释放线程的控制,以使其他操作运行“而你等待”的主要动机。

因为使用回调的非阻塞/异步代码更难以编写,读取和维护,所以应该避免使用非阻塞代码,除非它会影响应用程序的性能和可伸缩性,或者它们在哪里由您正在使用的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有一个异步版本,但没有syncronous版本。当使用这些API时,显然你需要使你的代码异步。

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

+0

虽然这两个示例都是非阻塞的(通过正常的定义),因为添加两个数字不会导致cpu被阻止运行。 I/O操作通常会这样做。 – rob