为什么nodejs中的一些同步库坚持使用callback?

我是一个新的nodejs开发人员,我认为我了解nodejs的devise。

我可以理解,一些系统调用相关的库应该是asynchronous的。 这些工作将在不同的线程池中进行排队和处理,并在完成时通过callback进行通知。

但是,我不明白为什么一些非系统调用相关的库使用callback作为通信方法。 例如,xml2js库是用Javascript编写的,显然,这个parsing函数没有理由通过callback来返回状态。 它可以直接返回处理结果,增加代码的可读性。

我的问题是,是否有任何理由,一些nodejs库devise师坚持基于callback的通信,而不是仅仅使用返回值?

callback风格没有错。

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

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

后者的一个好的理由是,当你把你的库改为非阻塞时,API不必改变。

需要提醒的是,节点是低级别的非阻塞IO库。 如果你打算做一些类似于js2xml的工作,那么很显然你正在等待节点0.6来标准化Web工作者子stream程API,这样你就可以将繁重的工作发送给子stream程,并且以非阻塞的方式完成实际的工作。

要以非阻塞的方式执行此操作,您的API需要是asynchronous的(或者您需要将其构build到语言中)。

如果它不是asynchronous的,没有理由使用callback传递返回值。

我已经看到一些使用callback而不是回报的库只是为了传递错误,但在我看来,使用投掷更好,更清洁。

实际上就LibXMLparsing器实现而言。 你确定没有系统级的IO吗?

考虑一下你parsing的XML包含DTD或Schema的场景。 那么经常在XML-Parsers中完成的XInclude处理呢?

虽然没有根本原因,但是如果有一个不使用任何低级IOfunction的API来使用asynchronouscallback风格,您并不总是知道IO是否真的可能发生。

现在假定您知道您的XMLparsing器不执行任何IO,因为它不处理XInclude和DTD / Schemavalidation。 如果您因此决定采用“传统”返回值路由,那么您将永远无法实现XInclude处理或架构validation,而无需更改您的API。

所以,如果你正在编写一个API,你最好从一开始就进行asynchronous/callback,因为你永远不知道你以后想做什么。

callback在各种情况下都是有用的,例如当你迭代一些集合(由于某种原因封装)时:

 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); });