我把我上一篇博文献给了讨论为什么 ASP.NET 开发者需要了解 Node.js 。就像高中辩论赛那样,因为没有任何技术抉择(或者提议)可以凭空存在,我想试试看翻盘,于是我决定从对立面重新想几个 ASP.NET 开发者应该离 Node 远点的理由 (最起码我深思熟虑之后再做决定)。 哦别误会……我真的很喜欢 Node,而且我觉得它提出的概念和模式将在很长一段时间内,对服务端 Web 编程产生深远的影响。即使随着时间的推移 Node 过气了,我们肯定可以从下一个牛逼玩意身上或多或少的感觉到它的影响(不管好的和/或坏的)。而在这期间,我们中很多人都会选择它,幸福的在一起,生产。 不过条条大路通罗马,虽然现在 Node 可能是"当红炸子鸡",不过这不意味着在Web 服务器上没它不行。每天都有大批的实际有效的产品交货,用那些巨无聊的老框架,比如说 ASP.NET, Java EE, Rails, PHP(!)还有数不清的各种。好吧,甚至还有些疯嘿用 COBOL 搭起了 HTTP 服务! COBOL 的 MVC … diao炸了。我给320个赞(不过千万别让我去干这事)。 对于在这个行业呆了近二十年有点看破红尘的我来说(摊手),好处就是… Node 提出了一个比较新的有意思的方式来解决那些比较老的无聊的问题。这不是贬低Node。只是说,它不是唯一,昨天不是今天不是明天也不会是。 综上……如果你是个 ASP.NET 程序员然后辞了职找 Node 的工作,来啊!给我发 email 或者 tweet,让我知道你能干啥 (要么干脆直接发简历……我们有在招聘哦!)。不过你如果还很迷茫,纠结于那些 Node-fanboy-love 的反对言论的话……继续读下去。 1. Node最好的功能(异步I/O)在.NET中已经存在了对Node最大的论据之一:Node通过使用异步非阻塞模型来处理那些潜在的长时间运行的I/O操作。这意味着大多数在你web应用的服务器端运行的工作(数据库查询、外部请求web service和其他的网络资源、访问文件等等)不会在你处理请求的主线程中发生,可以放心的继续处理其他对本站的HTTP请求。出于这个目的,Node会维护一个线程池,那些工作将被专门调度给一个可用的线程。你可以定义一个回调函数,当其中一个需要长时间运行的操作完成并返回时,Node将为你调用这个函数。这里有一个使用mongoose.js API来查询MongoDB的例子。注意回调函数的参数以及调用‘findOne’时缺乏返回值分配。
这类“连续传递”的编程风格有的时候对缺乏经验的人来说很难把握,特别是当你的代码嵌套了很多层的时候。 但对于我们熟悉的顺序风格(同步)来说还是有很大优势的:它为你的执行框架提供了一个自然点来做其他事情,而不是(在这个例子里)等待query.findOne()返回 。对Node来说,总有一些别的东西在处理发来的请求。确实, Node最初的设计目的就是因为典型web服务器端的生产瓶颈就是等待I/O的完成。Node的设计正是根据对这一点的观察,提供了很多性能的优势和扩展能力。 这里是对于Node的高级设计的描述: 所以如果你正在用Node,这很棒。不过有趣的是你在今天的ASP.NET中也可以使用相同的模式!可能许多人熟悉最初由C#5.0引入的async和await关键字。在.NET的web应用中使用它们再配合其他辅助框架比如ASP.NET,Entity Framework等同样可以取得像Node一样的非阻塞执行风格。 这里有一个简单的ASP.NET MVC控制器向Entity Framework进行查询的实现(这个模式换成Web API同样可行):
有没有发现每个方法是如何使用async/await来返回Task<ActionResult>而不是ActionResult?这个模式在语义上确保了和Node同样的连续执行风格。await关键字表明了执行暂停的位置(并且当前线程可以先去处理其他请求),此时EF查询在ASP.NET进程外执行。当EF查询返回时,另一个线程用于立即恢复位于'await'后面代码的执行。在ASP.NET中暂停/恢复给了我们如同Node中回调函数般的语义。实现虽然有差异,但基本原理是相同的,宝贵的服务器端资源不能浪费在等待昂贵I/O操作的完成。 一个警告:Node的支持者会告诉你Node的优势在于它的设计带领你直接进入“成功的坑”。异步是Node的默认模式,这对于Node来说非常容易,而同时你也可以在像ASP.NET这样的框架中使用异步,许多.NET开发者不这么认为,但这无疑是正确的。 虽然Node应用和ASP.NET应用比起来可能会更加“异步”,但不能理解成自身拥有更好的吞吐量或者更好的扩展性。应用的扩展性并不取决于你使用的框架,而在于你的应用本身是否有良好的扩展性。如果你现在在做APS.NET,在你觉得“ASP.NET缺乏扩展性”之前,花一些时间来学习并应用异步模型 。 |