无法理解node.js

don*_*ald 18 javascript javascript-events node.js

从没有JS经验的人那里,你推荐什么学习Node.js?

我在论坛上阅读了很多关于事件驱动,非阻塞,异步,回调等的内容,但我不知道那是什么!

我在哪里可以学习基础知识,以便了解所有术语和将来node.js?

谢谢!

Cor*_*rch 52

您提到的概念(事件驱动,非阻塞,异步,回调)并非特定于JavaScript,在更一般的上下文中理解它们是有价值的.它们都围绕着优雅地处理我们无法控制的资源.

想象一下,等待来自TCP连接的数据,等待操作系统删除文件,或等待用户点击按钮.如果您按照一步一步的方式对其进行编程(逐步进行同步),您就可以巡航 - "执行步骤1","执行步骤2","执行步骤3" - 直到您点击一步"等待事情发生".此时,您的程序将停止并拒绝让步,直到它收到数据,收到删除确认或收到按钮单击.换句话说,该调用阻止程序继续进行.考虑到可能需要我们注意的其他TCP连接,文件操作和UI操作并且不依赖于我们正在等待的项目,这是非常低效的.

在许多情况下,最好指出我们对资源感兴趣并在资源更改时接收逐步指令之外的通知.从您的概念列表:

  • 事件是我们感兴趣的资源的变化 - 我们的TCP连接收到了一些数据,文件删除完成,或者用户点击了一个按钮.
  • 异步调用告诉操作系统或运行时我们对使用资源做某事感兴趣.它们是非阻塞的 - 我们的程序可以在等待资源变化时处理其他事情.
  • 回调是资源更改时要执行的函数.异步资源调用通常接受对回调函数的一个或多个引用(一个用于成功,一个用于错误等).当资源发生更改时,运行时会调用相应的回调.

我们可以通过使用node.js重命名文件来看到这些概念:

var fs = require('fs');

// args (current file name, new file name, callback function)
fs.rename('/tmp/hello', '/tmp/world', function (err) {
  // this occurs when the rename is complete
  if (err) throw err;
  console.log('rename complete');
});
console.log('step after rename');
Run Code Online (Sandbox Code Playgroud)

第三个论点可能看起来很奇怪.它是一个未命名(匿名)函数,将在重命名完成时调用.

请注意,由于fs.rename是异步的,因此无法判断我们是否会首先看到"重命名完成"或"重命名后的步骤"消息.这是事件驱动/异步编程的缺点 - 如果我们有一组复杂的相互依赖的任务,我们需要非常小心地确保依赖任务在依赖它们的任务之前完成.异步调用完成的顺序可以改变的事实可能导致非常微妙的错误.

也可以看看:


根据唐纳德的要求编辑:

理解node.js的最佳方法是下载,构建,安装和使用它.你需要:

  • Mac OS或Linux.如果您对Cygwin感到满意,那也可能是一个选项,但如果您运行的是Windows,我发现在虚拟机中运行Linux会更容易.
  • Git - 不是必需的,但它使得获取代码库变得容易.
  • 一种调试应用程序的方法.看到这个问题.最初,将调试信息写入控制台可能会起作用.最终,您需要强大的调试功能.
  • 一个想法 - 你想用node.js做什么?如果您对其功能概述感兴趣,请浏览其API.

大多数教程都关注node.js快速构建Http服务器的能力:

请记住,node.js填补了一个非常特殊的利基 - 它旨在构建网络程序.它可能不是其他类型程序的正确工具.


Mar*_*sey 6

使用Node.js需要了解的基本概念是事件,事件发射器和事件侦听器.

在Node中,您可以调用的大多数函数都是非阻塞的.例如,当你调用fs.ReadStream()时,它会返回一个ReadableStream对象.该对象是一个EventEmitter,因此为了对流的内容执行任何操作,您需要将一个侦听器附加到该对象,该对象是在特定事件发生时被调用的函数.

所以像这样的工作:

var fs=require('fs');
var stream = fs.createReadStream("/var/log/messages", { 'flags':'r' });
stream.addListener('data', function(someData) {
        console.log(someData);
});
Run Code Online (Sandbox Code Playgroud)

这将读取给定文件中的所有文本,并将其写入控制台.当有数据要从流中读取时,将调用您的函数,并从文件中传递数据.

有趣的是,一旦没有更多数据要从文件中读取,脚本就会退出.只要有一个有效的事件监听器连接到发射器,或者另一个异步回调(如计时器)处于活动状态,节点就会一直运行.