为什么org/arangodb/request是同步的?

7
为什么新的JavaScript模块request是同步的?它只能在作业队列中使用吗?
在ArangoDB中有没有办法进行异步http(s)请求?

这个问题不应该被暂停。由于嵌入式操作环境的不同,它是有效的。实际上非常合理... - Brian Vanderbusch
@Brian Vanderbusch:不要混淆“有效”或“合法”与“主题相关”。当然,这个问题可能是有效的——只是它不属于这里,因为OP正在寻求外部资源。完全删除那一部分会使问题变得相关,但也会使你的答案过时。 - BoltClock
@BoltClock 感谢您的澄清。 - Brian Vanderbusch
@BoltClock 我已经重新措辞问题以符合规则。OP并不是在寻求外部资源,而是在寻找一种进行异步请求的方法(这在该平台上不受支持,因此对于外部资源的明确答案是“没有任何资源可用,也永远不会有”)。 - Alan Plum
@pluma:看起来不错,谢谢你的编辑。 - BoltClock
1个回答

8
全面披露:我是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都没有实现。

感谢您的关注和帮助,使得这个问题得以重新开放并得到解决和回答。同时也感谢您指出了我的回答中存在的问题。Arango文档非常好。我知道Foxx不使用node,因为单线程会影响Arango的其他部分,但我不知道Foxx在V8上是同步的。这让我更好地了解了何时扩展Arango时如何使用系统资源。 - Brian Vanderbusch
@BrianVanderbusch 感谢您的反馈。如果您在文档中发现任何需要改进的地方,请随时在GitHub上开启一个问题或在IRC上联系我。如果我的表达方式过于严厉,对此我深感抱歉。 - Alan Plum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接