506

我不完全了解Node.js的全部内容。也许是因为我主要是一个基于 Web 的业务应用程序开发人员。它是什么以及它的用途是什么?

到目前为止,我的理解是:

  1. 编程模型是事件驱动的,尤其是它处理I/O的方式。
  2. 它使用JavaScript,解析器是V8
  3. 它可以很容易地用于创建并发服务器应用程序。

我的理解正确吗?如果是,那么事件 I/O 的好处是什么,仅仅是并发的东西更多吗?另外,Node.js 的方向是成为一个框架,比如基于 JavaScript(基于 V8)的编程模型吗?

4

10 回答 10

618

我在工作中使用 Node.js,发现它非常强大。被迫选择一个词来描述 Node.js,我会说“有趣”(这不是一个纯粹的正面形容词)。社区充满活力和成长。JavaScript,尽管它很奇怪,但它可能是一种很好的编码语言。而且你每天都会重新思考自己对“最佳实践”和结构良好的代码模式的理解。现在有大量的想法涌入 Node.js,在其中工作会让你接触到所有这些想法——伟大的精神举重。

生产中的 Node.js 绝对是可能的,但与文档中看似承诺的“交钥匙”部署相去甚远。在 Node.js v0.6.x 中,“集群”已集成到平台中,提供了必不可少的构建块之一,但我的“production.js”脚本仍然有大约 150 行逻辑来处理诸如创建日志之类的事情目录,回收死工人等。对于“严肃”的生产服务,您还需要准备好限制传入连接并执行 Apache 为PHP所做的所有事情。公平地说,Ruby on Rails确实存在这个问题。它通过两种互补的机制来解决:1)将 Ruby 放在 Rails/Node 上。阿帕奇/ Lighttd)。网络服务器可以有效地提供静态内容、访问日志、重写 URL、终止SSL、执行访问规则以及管理多个子服务。对于命中实际节点服务的请求,网络服务器通过代理请求。2) 使用像Unicorn这样的框架来管理工作进程,定期回收它们等。我还没有找到一个看起来完全成熟的 Node.js 服务框架;它可能存在,但我还没有找到它,并且在我的手卷“production.js”中仍然使用约 150 行。

阅读Express之类的框架,似乎标准做法是通过一个万事通的 Node.js 服务来提供所有服务……“app.use(express.static(__dirname + '/public'))” . 对于低负载服务和开发,这可能没问题。但是,一旦您尝试将大量时间加载到您的服务上并让它 24/7 全天候运行,您就会很快发现推动大型网站拥有完善的、硬化的 C 代码(如Nginx )在他们的网站前面并处理所有内容的动机静态内容请求(...直到您设置CDN,如Amazon CloudFront))。对于这个有点幽默和毫不掩饰的负面看法,看看这个家伙

Node.js 也在发现越来越多的非服务用途。即使您使用其他东西来提供 Web 内容,您仍然可以使用 Node.js 作为构建工具,使用npm模块来组织您的代码,Browserify将其拼接成单个资产,并使用uglify-js将其缩小以进行部署. 对于处理网络,JavaScript 是一个完美的阻抗匹配,并且经常使它成为最简单的攻击途径。例如,如果你想通过一堆JSON响应负载来卑躬屈膝,你应该使用我的underscore-CLI模块,结构化数据的实用程序带。

优点缺点:

  • Pro:对于服务器人员来说,在后端编写 JavaScript 是学习现代 UI 模式的“门户药物”。我不再害怕编写客户端代码。
  • 优点:倾向于鼓励正确的错误检查(几乎所有回调都返回错误,让程序员去处理它;此外,async.js 和其他库处理“如果这些子任务中的任何一个失败则失败”范例比典型的同步代码更好)
  • 优点:一些有趣且通常困难的任务变得微不足道 - 例如获取飞行任务的状态、工作人员之间的通信或共享缓存状态
  • Pro:庞大的社区和大量基于可靠包管理器 (npm) 的优秀库
  • 缺点:JavaScript 没有标准库。你已经习惯了导入功能,以至于当你使用 JSON.parse 或其他不需要添加 npm 模块的内置方法时感觉很奇怪。这意味着所有内容都有五个版本。如果您对默认实现不满意,即使是 Node.js“核心”中包含的模块也有另外五个变体。这导致了快速演变,但也导致了某种程度的混乱。

与一个简单的每个请求一个进程的模型(LAMP)相比:

  • Pro:可扩展到数千个活动连接。非常快速且非常高效。对于 web 队列,这可能意味着与 PHP 或 Ruby 相比,所需的盒子数量减少了 10 倍
  • 优点:编写并行模式很容易。想象一下,您需要从Memcached获取三个(或 N 个)blob 。在 PHP 中执行此操作...您是否只是编写代码来获取第一个 blob,然后是第二个,然后是第三个?哇,好慢啊 有一个特殊的PECL模块可以解决 Memcached 的特定问题,但是如果您想在数据库查询的同时获取一些 Memcached 数据怎么办?在 Node.js 中,因为范式是异步的,让一个 Web 请求并行执行多项操作是很自然的。
  • 缺点:异步代码从根本上说比同步代码更复杂,而且对于开发人员来说,如果不深入了解并发执行的实际含义,前期学习曲线可能会很困难。尽管如此,这比编写任何类型的带锁定的多线程代码要简单得多。
  • 缺点:如果一个计算密集型请求运行例如 100 毫秒,它将停止处理在同一个 Node.js 进程中正在处理的其他请求...... AKA,cooperative-multitasking。这可以通过 Web Workers 模式来缓解(分离出一个子流程来处理昂贵的任务)。或者,您可以使用大量 Node.js 工作人员,并且只让每个工作人员同时处理一个请求(仍然相当有效,因为没有进程回收)。
  • 缺点:运行生产系统比Apache + PHP、PerlRuby等CGI模型复杂得多。未处理的异常将导致整个过程停止,需要逻辑来重启失败的工作人员(请参阅集群)。带有错误本机代码的模块可能会使该过程严重崩溃。每当工作人员死亡时,它正在处理的任何请求都会被丢弃,因此一个有缺陷的 API 很容易降低其他共同托管 API 的服务。

与用 Java / C# / C 编写“真正的”服务(C?真的吗?)

  • 优点:在 Node.js 中做异步比在其他任何地方做线程安全更容易,并且可以说提供了更大的好处。Node.js 是迄今为止我工作过的最不痛苦的异步范例。有了好的库,它只比编写同步代码稍微难一点。
  • 优点:没有多线程/锁定错误。诚然,您预先投资于编写更详细的代码,以表达没有阻塞操作的适当异步工作流。而且您需要编写一些测试并使其工作(它是一种脚本语言,并且仅在单元测试时才捕获到胖指法变量名称)。但是,一旦你开始工作,heisenbugs的表面积——在一百万次运行中只出现一次的奇怪问题——表面积要小得多。编写 Node.js 代码的税费被大量预先加载到编码阶段。然后你往往会得到稳定的代码。
  • 优点:JavaScript 在表达功能方面要轻得多。很难用文字来证明这一点,但是JSON、动态类型、lambda 表示法、原型继承、轻量级模块等等……它只是倾向于用更少的代码来表达相同的想法。
  • Con:也许你真的,真的很喜欢 Java 中的编码服务?

有关 JavaScript 和 Node.js 的另一个观点,请查看从 Java 到 Node.js,这是一篇关于 Java 开发人员学习 Node.js 的印象和经验的博客文章。


模块 在考虑节点时,请记住,您选择的 JavaScript 库将定义您的体验。大多数人至少使用两个,一个异步模式助手(Step、Futures、Async)和一个 JavaScript 糖模块(Underscore.js)。

助手/JavaScript 糖:

  • Underscore.js - 使用它。去做就对了。它使用 _.isString() 和 _.isArray() 之类的东西使您的代码变得美观和可读。我不确定您如何编写安全代码。此外,对于增强的命令行功能,请查看我自己的Underscore-CLI

异步模式模块:

  • Step - 一种非常优雅的方式来表达串行和并行动作的组合。我个人的推荐。请参阅我的帖子,了解步骤代码的外观。
  • 期货- 更加灵活(这真的是一件好事吗?)通过需求表达订购的方式。可以表示“并行启动a、b、c。A、B完成后启动AB。A、C完成后启动AC。” 这种灵活性需要更加小心以避免工作流程中的错误(例如从不调用回调,或多次调用它)。请参阅Raynos关于使用期货的帖子(这是让我“获得”期货的帖子)。
  • Async - 更传统的库,每种模式都有一种方法。在我虔诚地转换为 step 并随后意识到 Async 中的所有模式都可以用一个更易读的范式在 Step 中表达之前,我从这个开始。
  • TameJS - 由 OKCupid 编写,它是一个预编译器,添加了一种新的语言原语“等待”,用于优雅地编写串行和并行工作流。该模式看起来很神奇,但它确实需要预编译。我还在想这个。
  • StreamlineJS - TameJS 的竞争对手。我倾向于驯服,但你可以自己决定。

或者要阅读有关异步库的所有信息,请参阅与作者的小组访谈

网络框架:

  • Express Great Ruby on Rails-esk 框架,用于组织网站。它使用JADE作为 XML/HTML 模板引擎,这使得构建 HTML 变得不那么痛苦,甚至几乎是优雅的。
  • jQuery虽然在技术上不是一个节点模块,但 jQuery 正在迅速成为客户端用户界面的事实标准。jQuery 提供了类似 CSS 的选择器来“查询”可操作的 DOM 元素集(集处理程序、属性、样式等)。同样,Twitter 的Bootstrap CSS 框架、用于MVC模式的Backbone.js和用于将所有 JavaScript 文件拼接到单个文件中的Browserify.js 。这些模块都已成为事实上的标准,因此如果您还没有听说过它们,至少应该检查一下它们。

测试:

  • JSHint - 必须使用;起初我没有使用它,现在似乎难以理解。JSLint 添加了一堆使用 Java 等编译语言获得的基本验证。不匹配的括号,未声明的变量,许多形状和大小的类型。您还可以打开我称之为“肛门模式”的各种形式,您可以在其中验证空格的样式和诸如此类的东西,如果那是您的一杯茶,那就可以了-但真正的价值来自获得对确切行号的即时反馈,其中您忘记了结束“)”......而无需运行您的代码并打到有问题的行。“JSHint” 是Douglas CrockfordJSLint的更可配置的变体。
  • 我开始更喜欢 Vows 的Mocha竞争对手。两个框架都很好地处理了基础知识,但复杂的模式往往更容易在 Mocha 中表达。
  • Vows Vows 真的很优雅。它会打印出一份可爱的报告(--spec),显示哪些测试用例通过/失败。花 30 分钟学习它,您可以轻松地为您的模块创建基本测试。
  • Zombie - 使用JSDo作为虚拟“浏览器”对 HTML 和 JavaScript 进行无头测试。很强大的东西。将它与Replay结合起来,对浏览器内的代码进行闪电般的快速确定性测试。
  • 关于如何“思考”测试的评论:
    • 测试是非可选的。对于像 JavaScript 这样的动态语言,很少有静态检查。例如,将两个参数传递给期望为 4 的方法在执行代码之前不会中断。在 JavaScript 中创建错误的门槛很低。基本测试对于弥补编译语言的验证差距至关重要。
    • 忘记验证,只需让您的代码执行。对于每种方法,我的第一个验证案例都是“没有中断”,这是最常触发的案例。证明你的代码在没有抛出的情况下运行可以捕获 80% 的错误,并且会大大提高你的代码信心,以至于你会发现自己返回并添加你跳过的细微的验证用例。
    • 从小处着手,打破惯性障碍。我们都很懒惰,时间紧迫,很容易将测试视为“额外工作”。所以从小处着手。编写测试用例 0 - 加载您的模块并报告成功。如果你强迫自己做这么多,那么测试的惯性障碍就会​​被打破。这是你第一次做不到 30 分钟,包括阅读文档。现在编写测试用例 1 - 调用您的方法之一并验证“没有中断”,也就是说,您没有收到错误消息。测试用例 1 应该花费您不到一分钟的时间。随着惯性的消失,逐步扩展测试覆盖范围变得很容易。
    • 现在用你的代码改进你的测试。不要被模拟服务器的“正确”端到端测试所吓倒。代码从简单开始并不断发展以处理新案例;测试也应该。当您向代码添加新案例和新复杂性时,请添加测试案例来练习新代码。当您发现错误时,添加验证和/或新案例以覆盖有缺陷的代码。当你在调试并且对一段代码失去信心时,返回并添加测试以证明它正在做你认为的事情。捕获示例数据字符串(来自您调用的其他服务、您抓取的网站等)并将它们提供给您的解析代码。这里有几个案例,那里改进了验证,你最终会得到高度可靠的代码。

此外,请查看推荐的 Node.js 模块的官方列表。然而,GitHub 的 Node Modules Wiki要完整得多,也是一个很好的资源。


要了解 Node,考虑一些关键的设计选择会很有帮助:

Node.js 是基于事件异步/非阻塞的. 事件,如传入的 HTTP 连接将触发一个 JavaScript 函数,该函数会做一些工作并启动其他异步任务,如连接到数据库或从另一台服务器提取内容。一旦这些任务被启动,事件函数就会结束,Node.js 会重新进入睡眠状态。一旦发生其他事情,例如建立数据库连接或外部服务器响应内容,回调函数就会触发,并且执行更多 JavaScript 代码,可能会启动更多异步任务(例如数据库查询)。通过这种方式,Node.js 将愉快地为多个并行工作流交错活动,在任何时间点运行任何未被阻塞的活动。这就是为什么 Node.js 在管理数千个同时连接方面做得如此出色的原因。

为什么不像其他人一样每个连接只使用一个进程/线程?在 Node.js 中,新连接只是一个非常小的堆分配。启动一个新进程需要更多的内存,在某些平台上是一兆字节。但真正的成本是与上下文切换相关的开销。当你有 10^6 个内核线程时,内核必须做很多工作来确定下一个应该执行的人。为 Linux 构建 O(1) 调度程序已经投入了大量工作,但最终,与 10^6 个进程竞争 CPU 时间相比,拥有单个事件驱动进程的效率要高得多。此外,在过载情况下,多进程模型的行为非常糟糕,导致关键的管理和管理服务,尤其是 SSHD(这意味着您甚至无法登录到盒子来弄清楚它到底有多糟糕)。

Node.js 是单线程和无的。Node.js,作为一个非常慎重的设计选择,每个进程只有一个线程。正因为如此,多个线程同时访问数据基本上是不可能的。因此,不需要锁。线程很难。真的真的很难。如果您不相信这一点,那么您还没有完成足够多的线程编程。正确锁定很难,并且会导致很难追踪的错误。消除锁和多线程使最讨厌的错误类别之一消失了。这可能是 node.js 的最大优势。

但是如何利用我的 16 芯盒子呢?

两种方式:

  1. 对于像图像编码这样的大型计算任务,Node.js 可以启动子进程或向其他工作进程发送消息。在此设计中,您将有一个线程管理事件流,而 N 个进程执行繁重的计算任务并占用其他 15 个 CPU。
  2. 为了扩展 Web 服务的吞吐量,您应该在一个机器上运行多个 Node.js 服务器,每个核心一个,使用集群(使用 Node.js v0.6.x,此处链接的官方“集群”模块替换了具有不同的 API)。然后,这些本地 Node.js 服务器可以在套接字上竞争以接受新连接,从而平衡它们之间的负载。一旦一个连接被接受,它就会紧密地绑定到这些共享进程中的一个。从理论上讲,这听起来很糟糕,但实际上它工作得很好,并且可以让您避免编写线程安全代码的麻烦。此外,这意味着 Node.js 获得了出色的 CPU 缓存亲和力,更有效地使用了内存带宽。

Node.js 让您可以毫不费力地做一些非常强大的事情。假设您有一个 Node.js 程序,它执行各种任务,在TCP端口上侦听命令,对一些图像进行编码,等等。使用五行代码,您可以添加一个基于 HTTP 的 Web 管理门户,该门户显示活动任务的当前状态。这很容易做到:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");

现在您可以点击 URL 并检查正在运行的进程的状态。添加几个按钮,您就有了一个“管理门户”。如果您有一个正在运行的 Perl / Python / Ruby 脚本,那么仅仅“投入管理门户”并不是很简单。

但是 JavaScript 不是慢/坏/邪恶/魔鬼的产物吗?JavaScript 有一些奇怪的地方,但“好的部分”有一种非常强大的语言,无论如何,JavaScript 是客户端(浏览器)上的语言。JavaScript 将继续存在;其他语言将其定位为 IL,世界一流的人才正在竞相生产最先进的 JavaScript 引擎。由于 JavaScript 在浏览器中的作用,大量的工程工作被投入到使 JavaScript 快速运行。 V8是最新最好的 javascript 引擎,至少在这个月是这样。它在效率和稳定性方面都击败了其他脚本语言(看着你,Ruby)。只有在微软、谷歌和 Mozilla 的庞大团队致力于解决这个问题,竞争构建最好的 JavaScript 引擎时,它才会变得更好(它不再是 JavaScript“解释器”,因为所有现代引擎都执行大量的JIT在引擎盖下编译,解释仅作为一次执行代码的后备)。是的,我们都希望我们可以修复一些奇怪的 JavaScript 语言选择,但这真的没那么糟糕。而且该语言非常灵活,以至于您实际上不是在编写 JavaScript,而是在编写 Step 或 jQuery —— 与任何其他语言相比,在 JavaScript 中,库定义了体验。无论如何,要构建 Web 应用程序,您几乎都必须了解 JavaScript,因此在服务器上使用它进行编码具有某种技能组合的协同作用。它让我不再害怕编写客户端代码。

此外,如果你真的讨厌 JavaScript,你可以使用像CoffeeScript这样的语法糖。或任何其他创建 JavaScript 代码的东西,例如Google Web Toolkit (GWT)。

说到 JavaScript,什么是“闭包”?- 几乎可以说您在调用链中保留词法范围的变量。;) 像这样:

var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
    database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();

看看你如何可以只使用“myData”而不做任何尴尬的事情,比如将它存储到一个对象中?与 Java 不同,“myData”变量不必是只读的。这种强大的语言特性使异步编程变得不那么冗长和痛苦。

编写异步代码总是比编写简单的单线程脚本更复杂,但使用 Node.js,这并没有那么困难,而且除了效率和可扩展至数千个并发连接之外,您还可以获得很多好处。 ..

于 2011-07-21T20:37:07.423 回答
213

我认为优点是:

  1. 在速度极快的虚拟机 (V8) 上使用动态语言 (JavaScript) 进行 Web 开发。它比 Ruby、Python 或 Perl 快得多。

  2. 能够在单个进程上以最小的开销处理数千个并发连接。

  3. JavaScript 非常适合具有一流函数对象和闭包的事件循环。人们已经知道如何以这种方式使用它,并在浏览器中使用它来响应用户发起的事件。

  4. 很多人已经知道 JavaScript,即使是那些不自称是程序员的人。它可以说是最流行的编程语言。

  5. 在 Web 服务器和浏览器上使用 JavaScript 可以减少两个编程环境之间的阻抗不匹配,这两个编程环境可以通过 JSON 通信数据结构,在等式的两边都工作相同。可以在服务器和客户端之间共享重复的表单验证代码等。

于 2009-12-14T19:37:02.673 回答
85

V8是 JavaScript 的实现。它允许您运行独立的 JavaScript 应用程序(除其他外)。

Node.js 只是一个为 V8 编写的库,它执行事件 I/O。这个概念解释起来有点棘手,我相信有人会用比我更好的解释来回答......要点是,与其做一些输入或输出并等待它发生,你只是不要等待让它完成。例如,询问文件的最后编辑时间:

// Pseudo code
stat( 'somefile' )

这可能需要几毫秒,也可能需要几秒钟。使用事件I/O,您只需触发请求,而不是等待您附加一个在请求完成时运行的回调:

// Pseudo code
stat( 'somefile', function( result ) {
  // Use the result here
} );
// ...more code here

这使它很像浏览器中的 JavaScript 代码(例如,具有Ajax风格的功能)。

有关更多信息,您应该查看文章Node.js 真的很令人兴奋,这是我对库/平台的介绍......我发现它非常好。

于 2009-12-10T23:19:00.763 回答
35

Node.js是为服务器端 JavaScript 代码构建的开源命令行工具。您可以下载tarball,编译并安装源代码。它允许您运行 JavaScript 程序。

JavaScript由 Google 开发的用于Chrome浏览器的 JavaScript 引擎V8执行。它使用 JavaScript API 来访问网络和文件系统。

它因其性能和执行并行操作的能力而广受欢迎。

理解 node.js是我目前找到的对node.js最好的解释。

以下是有关该主题的一些好文章。

于 2011-01-04T10:12:43.227 回答
13

闭包是在创建代码的上下文中执行代码的一种方式。

这对并发性意味着您可以定义变量,然后启动一个非阻塞I/O函数,并向其发送一个匿名函数以进行回调。

当任务完成时,回调函数将在带有变量的上下文中执行,这就是闭包。

闭包非常适合编写具有非阻塞 I/O 的应用程序的原因是它非常容易管理异步执行的函数的上下文。

于 2010-04-12T00:56:40.200 回答
8

两个很好的例子是关于如何管理模板和使用渐进增强。您只需要一些轻量级的 JavaScript 代码就可以使其完美运行。

我强烈建议您观看并阅读以下文章:

选择任何一种语言并尝试记住您将如何管理 HTML 文件模板以及在DOM结构中更新单个CSS类名称必须执行的操作(例如,用户单击了菜单项并且您希望将其标记为“选择”并更新页面内容)。

使用 Node.js,它就像在客户端 JavaScript 代码中一样简单。获取您的 DOM 节点并将您的 CSS 类应用于该节点。获取您的 DOM 节点和 innerHTML 您的内容(您将需要一些额外的 JavaScript 代码来执行此操作。阅读文章以了解更多信息)。

另一个很好的例子是,您可以使用同一段代码使您的网页与打开或关闭的 JavaScript 兼容。想象一下,您有一个用 JavaScript 进行的日期选择,允许您的用户使用日历选择任何日期。您可以编写(或使用)相同的 JavaScript 代码,使其在您的 JavaScript 打开或关闭的情况下工作。

于 2011-02-28T23:44:30.443 回答
7

有一个很好的快餐店类比,最能解释 Node.js 的事件驱动模型,请参阅完整文章Node.js、医生办公室和快餐店 - 了解事件驱动编程

这是一个摘要:

如果快餐店遵循传统的基于线程的模式,您会订购食物并排队等候直到收到。在您完成订单之前,您身后的人将无法订购。在事件驱动模型中,您订购食物然后排队等候。然后其他人都可以自由订购。

Node.js 是事件驱动的,但大多数 Web 服务器都是基于线程的。York 解释了 Node.js 的工作原理:

  • 您使用 Web 浏览器在 Node.js Web 服务器上发出“/about.html”请求。

  • Node.js 服务器接受您的请求并调用一个函数从磁盘检索该文件。

  • 当 Node.js 服务器正在等待检索文件时,它会为下一个 Web 请求提供服务。

  • 检索文件时,会在 Node.js 服务器队列中插入一个回调函数。

  • Node.js 服务器执行该函数,在这种情况下将呈现“/about.html”页面并将其发送回您的 Web 浏览器。”

于 2011-12-19T23:28:53.527 回答
6

嗯,我明白了

  • Node 的目标是提供一种简单的方法来构建可扩展的网络程序。
  • Node 在设计上类似于 Ruby 的 Event Machine 或 Python 的 Twisted 等系统,并受其影响。
  • V8 javascript 的事件 I/O。

对我来说,这意味着你在所有三个假设中都是正确的。图书馆看起来很有希望!

于 2009-12-10T23:17:25.163 回答
6

另外,别忘了提到 Google 的 V8 非常快。它实际上将 JavaScript 代码转换为具有已编译二进制性能的机器代码。因此,与所有其他伟大的事情一起,它的速度非常快。

于 2011-11-29T15:15:38.277 回答
3

问:编程模型是事件驱动的,尤其是它处理I/O的方式。

正确的。它使用回调,因此任何访问文件系统的请求都会导致请求被发送到文件系统,然后 Node.js 将开始处理它的下一个请求。一旦从文件系统得到响应,它只会担心 I/O 请求,此时它将运行回调代码。但是,可以进行同步 I/O 请求(即阻塞请求)。开发人员可以在异步(回调)或同步(等待)之间进行选择。

问:它使用 JavaScript,解析器是 V8。

是的

问:它可以很容易地用于创建并发服务器应用程序。

是的,尽管您需要手动编写大量 JavaScript。最好查看一个框架,例如http://www.easynodejs.com/ - 它带有完整的在线文档和示例应用程序。

于 2012-03-09T12:47:57.490 回答