全面披露:我是ArangoDB开发团队的一员,主要负责Foxx和所有的JavaScript。我也是编写org/arangodb/request模块的人。
ArangoDB与Node.js不同,尽管它们有很多相似之处(例如使用V8 JavaScript引擎)。与Node.js(或浏览器)不同,ArangoDB使用基于线程的并发模型,并且没有事件循环。但是,线程在JavaScript中不会暴露出来(实际上,在V8中每个线程都是完全隔离的),因此通常你甚至不必考虑它们。
在浏览器和Node.js中,像setTimeout这样的函数通过事件循环延迟代码执行(直到一定时间或外部事件发生为止)。
在ArangoDB中,代码始终按顺序执行。例如,将传入的HTTP请求传递给JavaScript中的Foxx控制器,并在控制器返回后立即发送响应。即使可以使用setTimeout,你正在使用的外部资源(甚至是“内部”资源,如文档集合和事务)也可能在延迟代码执行之前就已经消失了。
因此,org/arangodb/request模块提供的request函数也完全是同步的。它不会返回promise或接受回调,而是直接返回传入的响应数据。 它也决不是npm上的request模块,而是一个基于该模块API的同步实现,只要在Node.js之外实现其API可能性(例如不包括流并返回远程响应,而不是接受回调)。
如果你来自Node.js/io.js背景,这可能会感觉很奇怪,因为非阻塞IO可以实现更高的吞吐量,但请记住,ArangoDB和Node.js的设计目标非常不同。Node.js围绕着流和网络连接构建,而ArangoDB则作为持久数据存储构建,并且必须处理事务和锁定。
如果您有较高的网络延迟或者外部API响应对客户端响应不重要的情况下,最好不要直接从Foxx控制器访问外部API。这就是Foxx队列的用途。交易电子邮件是一个典型的例子。
虽然Foxx非常灵活,但它的主要重点是允许您将大多数应用程序(特别是从数据中获益的逻辑)直接移入数据库中。对于小到中等规模的项目,您可能可以在内部执行外部API调用。 但是,如果您的应用程序主要涉及通过网络与其他服务通信,则在数据库中运行该代码可能不是最佳解决方案。
幸运的是,ArangoDB很好地配合其他产品使用,因此如果您发现在高负载下它成为性能瓶颈,则可以轻松地将网络密集型代码移出Foxx。 Foxx并没有消除应用服务器的需要,但它可以显著减少它们的复杂性。
作为对Brian答案的更正:遗憾的是,Promise也不能让你在同步环境中编写异步代码。
Promises/A+规范将Promise定义为必须异步执行。在不支持原生Promise的情况下,仍然必须基于现有函数(如setTimeout或process.nextTick)构建Promise,而ArangoDB都没有实现。