为什么新的JavaScript模块request是同步的?是否应该仅在作业队列中使用它?
有什么方法可以在ArangoDB中发出异步http(s)请求?
最佳答案
全面披露:我是ArangoDB开发团队的成员,主要从事Foxx和所有JavaScript的工作。我也是编写org/arangodb/request
模块的人。
尽管有许多相似之处(例如使用V8 JavaScript引擎),但ArangoDB与Node.js的环境不同。与Node.js(或浏览器)不同,ArangoDB使用基于线程的并发模型,并且没有事件循环。但是,线程并未在JavaScript中公开(实际上,在V8中,每个线程都是完全隔离的),因此您通常甚至不必考虑它们。
在浏览器和Node.js中,像setTimeout
这样的功能通过延迟事件循环(直到经过一定时间或直到发生外部事件)来延迟代码执行。
在ArangoDB中,代码始终线性执行。例如,传入的HTTP请求将通过JavaScript传递给Foxx Controller ,并在 Controller 返回后立即发送响应。即使您可以使用setTimeout
,您正在使用的外部资源(或什至是“内部”资源,例如文档集合和事务)也可能在延迟代码执行时就已经消失了。
因此,request
模块提供的org/arangodb/request
函数也完全同步。无需返回 promise 或进行回调,而是直接返回传入的响应数据。它绝对不是与npm上的request
相同的模块,而是基于该模块API的同步实现,以至于可以在Node.js外部实现其API(例如,不包括流并返回远程响应而不是执行回调) 。
如果您来自Node.js/io.js,那么这可能会感到不对劲,因为非阻塞IO可以实现更高的吞吐量,但是请记住,ArangoDB和Node.js的设计目标是非常不同的。 Node.js是围绕流和网络连接构建的。 ArangoDB构建为持久数据存储,并且必须处理事务和锁。
如果您很可能会出现严重的网络延迟,或者如果外部API的响应对于客户端响应不是必需的,那么直接从Foxx Controller 访问外部API可能不是最好的主意。这就是Foxx队列的目的。交易电子邮件就是一个很好的例子。
尽管Foxx具有多种用途,但其主要重点是允许您将大多数应用程序(尤其是得益于靠近数据的运行逻辑)直接移动到数据库中。对于中小型项目,您可能可以通过外部API进行入站调用。但是,如果您的应用程序主要关注与网络上的其他服务进行通讯,则在数据库中运行该代码可能不是最佳解决方案。
幸运的是,ArangoDB在其他方面表现出色,因此,如果您发现网络密集型代码在更高负载下成为性能瓶颈,则很容易将其从Foxx中移出。 Foxx并没有消除对应用服务器的需求,但是可以大大降低其复杂性。
作为对Brian答案的更正:可悲的是,promise也不会让您在同步环境中编写异步代码。 Promises/A+ spec将promise定义为必须异步执行。在没有 native 支持的地方,它们仍然必须建立在现有函数(例如setTimeout
或process.nextTick
)的基础上,而这两个ArangoDB都没有实现。
关于javascript - 为什么org/arangodb/request是同步的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29150050/