为什么nodejs中的某些同步库坚持使用回调?

时间:2011-04-13 13:43:50

标签: node.js

我是一个新的nodejs开发人员,我认为我理解nodejs的设计。

我可以理解一些与系统调用相关的库应该是异步的。这些作业将在不同的线程池中排队并处理,并在完成后通过回调通知。

但是,我无法理解为什么一些非系统调用相关的库使用回调作为通信方法。例如,xml2js库是用Javascript编写的,显然,这个解析函数没有理由通过回调返回状态。它可以直接返回处理结果,并且代码可读性会提高。

我的问题是,是否有任何理由让某些nodejs库设计师坚持基于回调的通信而不仅仅是使用返回值?

4 个答案:

答案 0 :(得分:5)

回调风格没有任何问题。

var return = doSomething();
...

doSomething(function(return) {
    ...
});

这是首选。他们都有效。前者似乎只是“更好”,因为你已经习惯了。

后者的一个很好的理由是,当您将库更改为非阻塞时,不必更改API。

需要提醒的是,节点是一个低级非阻塞IO库。如果您要执行类似js2xml的操作,那么显然您正在等待节点0.6来标准化Web worker子流程API,这样您就可以将繁重的工作发送到子流程,并以非阻塞的方式进行实际的艰苦工作。

要以非阻塞的方式执行此操作,您的API需要是异步的(或者您需要将其构建为语言)。

答案 1 :(得分:3)

如果它不是异步的,则没有理由使用回调来传递返回值。

我见过一些使用回调而不是返回的库只是为了传回错误,但在我看来,使用throws更好更清洁。

答案 2 :(得分:1)

实际上就LibXML解析器实现而言。你确定没有系统级IO可用吗?

考虑您解析的XML包含DTD或Schema的场景。那些经常在XML-Parsers中完成的XInclude处理呢。

虽然没有根本原因,但要使用不使用任何低级IO函数的API来使用异步回调样式,您并不总是知道是否存在IO实际可能发生的情况。

现在假设您知道您的XML-Parser没有执行任何IO,因为它不处理XInclude和DTD / Schema验证。因此,如果您决定采用“传统”返回值路由,那么在不更改API的情况下,您将永远无法实现XInclude Processing或Schema验证。

通常,如果您正在编写API,那么最好从一开始就进行异步/回调,因为您永远不知道以后要做什么。

答案 3 :(得分:0)

回调在各种场景中都很有用,例如当你在迭代某些集合时(由于某种原因封装):

function Foo() {
    this._data = [1, 2, 3, 4, 5]; 
}

Foo.prototype.forEach = function(callback) {
    var i, 
        len = this._data.length;

    for(i = 0; i < len; i++) {
        callback("Item number: " + this._data[i]);
    }
}

var foo = new Foo();

foo.forEach(function(item) {
    console.log(item);
});