本文为您分享「Node.js 入门你须要知道的 10 个问题」这些问题可能也是面试中会被问到的,固然问题不只仅是这 10 道,所以,最近开源了一个新项目 Nodejs-Interview-Questions 专一于 Node.js 面试题的分享,提供了中英文版本,您也能够在线预览: https://interview.nodejs.red/html
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。它是一个开源和跨平台的服务端应用程序。任何人均可以编写 JavaScript 代码来开发 Node.js 应用程序。它能够运行于 Microsoft Windows、Linux、 或 OS 系统。前端
Node.js 不是一个新的语言,也不只仅是一个基于 JavaScript 的框架,它基于 Chrome 的 JavaScript 运行时,所以代码的编写和执行与浏览器很是类似。node
Node.js 功能ios
如下是 Node.js 的一些重要功能git
Node.js 使用的单线程模型且采用了事件循环架构,使得编写可扩展性高的服务器变得既容易又安全。一些传统的服务端语言会建立多线程来处理请求,一般建立线程都是有系统资源开销的,所以也会有一些限制,而 Node.js 只建立一个线程来处理更多的请求。github
Node.js 的全部 API 都是异步的。这意味着下一个请求来临时能够直接处理而不用等待上一次的请求结果先返回。面试
Node.js 从不缓冲任何任何数据,参见What is No-Buffering feature of Node.jssql
咱们许多人可能会对 Node.js 感到困惑。它不是像 Apache 这样的 Web 服务器。Node.js 提供了一种新方法来执行咱们的代码。它是 JavaScript 的运行时。Node.js 提供了建立 HTTP 服务器的方法,咱们能够在这之上托管咱们的应用程序。npm
Source: Introduction To Node.js编程
咱们能够从 Node.js 官方网站 https://nodejs.org/en/ 下载安装软件。
nvm 安装
这里推荐您使用 nvm 工具安装,方便后期的升级进行 Node.js 版本管理,如下为安装步骤:
验证安装结果
在 Node.js 安装成功以后,咱们能够检查它是否正常工做。
打开命令终端,输入如下命令
$ node
以后将出现 Node 提示符,咱们写入如下命令,运行查看
console.log("hello world!");
按 Enter 键
这是有陷阱的,在相似一些 Unix 系统中你不该该尝试监听 80 端口,这么作你须要拥有超级用户权限,所以,不推荐你这么作。
尽管如此,若是你必定要让应用监听 80 端口,可使用 Nginx 来实现,在应用前方加上一层反向代理。仍是建议你监听大于 1024 的端口。
错误优先回调函数用于同时返回错误(error)和数据信息(data),返回值的第一个参数作为错误信息描述,而且验证它是否出错(非错 error 为 null),其它参数用于返回数据。
fs.readFile(filePath, function(err, data) { if (err) { // 错误信息处理 return console.log(err) } // return the data object return data; })
在 Node.js 中建立一个 Http 服务是很简单的一件事情,咱们能够经过 HTTP 模块来完成这些操做。
const http = require('http'); const server = http.createServer((request, response) => { if (request.url === '/hello') { response.writeHead(200, { 'Content-Type': 'text/plain', }); response.end('hello world!'); } else { response.end('OK!'); } }); server.listen(3000, '127.0.0.1', () => { console.log('service is listening at http://127.0.0.1:3000'); });
Node.js 的核心组建是系统 API、V8 引擎和 Libuv。
Libuv 库
libuv 库是一个跨平台的支持事件驱动的 I/O 库。它是使用 C 和 C++ 语言为 Node.js 所开发的。可是它也被应用于 Mozilla's 的 Rust、Luvit、Julia、pyuv 等其它的语言。
libuv 库是 I/O 操做的核心部分,例如读取文件和 OS 交互。
关于 Libuv 的学习,能够参考 libuv中文教程
V8 引擎
来自于谷歌:“V8 是谷歌开源的高性能 JavaScript 引擎”,使用 C++ 开发,并在谷歌浏览器中使用。V8 中实现的 ECMAScript 中指定 ECMA - 262 ,第 3版运行在 Windows XP 和 Vista、Mac OS X 的 10.5 和 Linux 系统使用 IA - 32 或 ARM/MIPS 处理器。V8 能够独立运行,也能够嵌入到任何 C++ 应用程序。
若是你感兴趣想学习更多的 V8 引擎,请访问 What is V8?
APIs (NodeJS Core Libs)
Node.js APIs 是根据您的请求去调用一些函数执行一些业务操做。默认状况下 Node.js 的 APIs 都是异步的,可是你想同步使用也是能够的(同步方式是不推荐的)。
例如,这个 fs 模块可使用同步方式也可使用异步方式。
var fs = require('fs'); fs.readFile('/files/help.txt', function(err, buf) { // use fs.readFileSync() for sync operation. console.log(buf.toString()); });
Source: Introduction to NodeJS, A SSJS: Part I - Components Explained
“回调地狱”是指严重的回调嵌套,这些回调嵌套使得代码变得难以阅读和维护。
如下是回调嵌套的示例:
query("SELECT clientId FROM clients WHERE clientName='picanteverde';", function(id){ query(`SELECT * FROM transactions WHERE clientId=${id}`, function(transactions){ transactions.each((transac) => { query(`UPDATE transactions SET value = ${transac.value*0.1} WHERE id=${transac.id}`, (error) => { if(!error){ console.log("success!!"); }else{ console.log("error"); } }); }); }); });
在某种程度上,修复“回调地狱”的方式是模块化。回调被分解为独立的函数,这些函数能够经过参数进行传递。因此,针对以上代码的第一个改进以下所示:
const logError = (error) => { if(!error){ console.log("success!!"); }else{ console.log("error"); } }, updateTransaction = (t) => { query(`UPDATE transactions SET value = ${t.value*0.1} WHERE id=${t.id}`, logError); }, handleTransactions = (transactions) => { transactions.each(updateTransaction); }, handleClient = (id) => { query(`SELECT * FROM transactions WHERE clientId=${id}`, handleTransactions); }; query("SELECT clientId FROM clients WHERE clientName='picanteverde';",handleClient);
尽管这个代码相比第一个示例更容易易读,并且咱们建立的的函数还能够获得复用。可是在某些状况下,咱们想要使程序更健壮可经过 Promise 来解决。
此外,generators 也提供了强大的回调地狱解决方案,使用它能够解决不一样回调之间的依赖关系。然而 generators 会更高级一些使用起来会复杂一些。关于 Generators 更多信息能够阅读这篇文章 Generators in Node.js
然而,以上的虽然能很好解决回调地狱问题,可是目前有了更好的方案 Async/Await。使用 Async/Await 须要注意 Node.js 版本要在 v7.5 版本之上。
Source: 8 Essential Node.js Interview Questions
事件驱动程序是由事件(click、load 等)决定的代码流程术语。它是当今流行编程语言(例如 C#、Java)里一个最基本的里程碑,在这里不会详细讲述。在 Node.js 中或者一些其它类型的 JavaScript 项目中,咱们都在使用事件驱动编程。也许你并不知道事件驱动编程,可是在一些页面加载或按钮单击事件中,你已经在使用了。
举一个典型的事件驱动流程的例子,看下它是如何在 Node.js 中完成中:
result = getJSONfromDestination(); binddata(result);
上述操做是一个阻塞 I/O(单线程模式下将会等待这个阻塞 I/O 完成以后才会进行下一步)
如今让咱们看看异步方式该如何进行(非阻塞 I/O 进程)
json_finished = function(result){ binddata(result); } getJSONfromDestination(jsonfinished);
如上所示,这是一个非阻塞的例子,由于 json_finished 不是你所想向的那样会直接工做。当您调用 getJSONfromDestination 函数并将 jsonfinished 作为参数传递时,它才开始工做。
Source: NodeJS Series #6: Event - Driven Programming
NPM 是 Node.js 中的包管理器。容许咱们为 Node.js 安装各类模块,这个包管理器为咱们提供了安装、删除等其它命令来管理模块。这里有一点咱们须要注意,咱们必需要有一个 package.json 文件或 node_modules 目录安装模块到本地。
NPM 最好的一点是它会在本地存储咱们所安装的依赖项,存在于 package.json 的 dependencies 对象里。例如,若是一个模块 X 使用了模块 A 版本为 1.0,模块 Y 使用了模块 A 版本为 1.5,那么模块 X 或 Y 都将在本地拥有本身对应的模块 A 的副本。
// 模块 X { "name": "X", "dependencies": { "A": "^1.0" } }
// 模块 Y { "name": "Y", "dependencies": { "A": "^1.5" } }
须要 NPM 包
当咱们在开发一些 Node.js 项目时,可能会遇到一些地方须要 NPM,例如连接 Redis、MongoDB 或者发送请求 Request 等,有了这些模块可使咱们更专一于业务开发,固然有时你会有些特别的需求,这时可能须要本身去封装一个 NPM 模块,实现复用。
点击下面 Source 阅读更多关于 NPM 的相关内容
Source: How to Create Nodejs Module and Publish Over to Npm
Node.js 能够作 Web 服务端、命令行工具 (Java, PHP 能够作的 JS 也能够作),如今让咱们看下 Node.js 的 10 个应用场景:
Source: What does node. js do? 10 application scenarios for node. js
本片文章首发于慕课网:https://www.imooc.com/article/289202