Node.jsasynchronous用例

最近,我一直在开发Web应用程序,我意识到我没有使用asynchronous属性。 因此,我结束了很多嵌套的callback。

例如,如果用户想通过特定的API从服务器获取文件,我将得到类似于此的代码,

db.query(<select list of permitted files_names>, function(err, filenames) { async.each(file_names, function(name, next) { //open each file to put into array }); }) 

这段代码需要查询数据库,以便在asynchronous循环之前获取文件名列表,并将每个文件内容放入一个数组中。 最后它会将完成的数组返回给客户端。

使用嵌套的callback和asynchronous库,这个代码的行为就像是一个同步代码。

 names = db.querySync(//select list of permitted files_names); for(name in names) { //open each file to put into array } 

我更喜欢写这样的同步代码,因为它很整洁。 我的用例可能有点奇怪,但我的API的大部分行为以类似的方式,这让我想为什么我甚至需要asynchronousfunction?

如果这两个编码在performance上有差异,有谁能指教我? 如何使用非阻塞属性来提高此用例的性能?

如果你正在使用asynchronous调用来定义你正在使用的callback函数。 callback函数在操作完成或出错时触发。 您不需要一个花哨的库来使用它们,这是Node的事件循环驱动子系统如何操作的骨干。

节点强烈build议不要使用“同步”呼叫。 Node核心只包括一小部分作为方便,他们作为最后的手段工具。 许多库甚至不支持它们,所以你绝对必须习惯编写asynchronous代码。 例如,在浏览器环境中,您无法使用阻止调用,而不会干扰JavaScript运行时并拖延页面。

我更喜欢使用Promises line Bluebird实现有序地保持代码。 还有其他的方法,像asynchronous库,可以帮助pipe理复杂的嵌套模式。

一些特权包括Promise.all方法运行一系列承诺完成,然后触发下一步, Promise.map迭代列表,为每个元素运行asynchronous代码,然后在列表完成时推进。

如果你有组织你的代码的纪律,这不是太糟糕。 Node比Ruby,Python或Java等传统的默认同步语言要求更多地关注操作的顺序,但是您可以习惯它。 一旦开始使用asynchronous代码而不是与之对抗,通常可以快速,高效地完成大量工作,并且在许多情况下比其他语言更有效,这些语言中必须处理线程以及locking和/或处理与IPC。

好处很简单:通过使用asynchronous代码,当前线程(记住,Node.js是单线程的)能够处理其他请求,而当前请求正在等待某个事件(如数据库查询)返回。

如果使用同步代码,当前线程将在等待时阻塞,同时将无法处理其他请求。 换句话说,你失去了并发性。


为了保持asynchronous代码的清洁,请查看承诺(避免深度嵌套的callback)和ES7asynchronous/等待(以避免callback,并编写看起来像同步代码的asynchronous代码)。

是的,两个代码在性能方面有所不同。

在同步代码中:

 names = db.querySync(//select list of permitted files_names); 

你在这里调用数据库来给出名字列表。 假设,这需要10秒。 所以这个时候,nodeJS因为它是单线程的gos进入阻塞状态。 10秒后,它执行其余的代码。 假设这个for循环需要5秒,一些代码需要5秒。

 for(name in names) { //open each file to put into array } //some code 

所以需要20秒的总时间。

而在asynchronous代码中:

 db.query(<select list of permitted files_names>, function(err, filenames) { 

NodeJs会要求数据库给一个callback名字列表。 假设需要10秒。 并立即进入下一步(某些代码),但不进入阻塞状态。 假设一些代码需要5秒。

 async.each(file_names, function(name, next) { //open each file to put into array }); }) //some code. 

5秒后,它将检查是否有I / O操作要执行。 一旦回电被返回。 它会在5秒内执行函数(name,next){..}。

所以这里的总时间是15秒。

以这种方式,性能得到改善。

如果asynchronous代码应该清晰整齐,那么就使用闭包和承诺。

例如:上面的asynchronous代码可以写成

 fun = function(err, filenames) { async.each(file_names, function(name, next) { //open each file to put into array } db.query(<select list of permitted files_names>, fun);