如今,愈来愈多的科技公司和开发者开始使用 Node.js 开发各类应用。Node.js除了可以辅助大前端开发外,还能够编写Web应用,封装Api,组装RPC服务等,甚至是开发VSCode编辑器同样的PC客户端。和其它技术相比, Node.js 简单易学,性能好、部署容易,可以轻松处理高并发场景下的大量服务器请求。Node.js 周边的生态也很是强大,NPM(Node包管理)上有超过60万个模块,日下超过载量3亿次。但编写 Node.js 代码对新人和其它语言背景的开发者来讲,不是一件容易的事,在入门以前须要弄懂很多复杂的概念。前端
a)Node.js简介vue
早在2007年,Jeff Atwood 就提出了著名的 Atwood定律
java
任何可以用 JavaScript 实现的应用系统,最终都必将用 JavaScript 实现node
固然了,Node.js 也有一些缺点。Node.js 常常被人们吐槽的一点就是:回调太多难于控制(俗称回调地狱)和 CPU 密集任务处理的不是很好。可是,目前异步流程技术已经取得了很是不错的进步,从Callback、Promise 到 Async函数,能够轻松的知足全部开发需求。至于 CPU 密集任务处理并不是不可解,方案有不少,好比经过系统底层语言 Rust 来扩展 Node.js,但这样会比较麻烦。笔者坚信在合适的场景使用合适的东西,尤为是在微服务架构下,一切都是服务,能够作到语言无关。若是你们想使 JavaScript 作 CPU 密集任务,推荐 Node.js 的兄弟项目 fibjs,基于纤程(fiber,能够简单理解为更轻量级的线程),效率很是高,兼容npm,同时没有异步回调烦恼。 b)什么是Node.js?mysql
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.react
npm
做为包管理器,目前 npm
是开源库里包管理最大的生态,功能强大,截止到2017年12月,模块数量超过 60 万+c)基本原理jquery
下面是一张 Node.js 早期的架构图,来自 Node.js 之父 Ryan Dahl 的演讲稿,在今天依然不过期,它简要的介绍了 Node.js 是基于 Chrome V8引擎构建的,由事件循环(Event Loop)分发 I/O 任务,最终工做线程(Work Thread)将任务丢到线程池(Thread Pool)里去执行,而事件循环只要等待执行结果就能够了。 git
![]()
![]()
核心概念程序员
Chrome
浏览器中被使用。Chrome V8 引擎能够独立运行,也能够用来嵌入到 C/C++ 应用程序中执行。libuv
提供)libuv
提供)梳理一下es6
libuv
由事件循环和线程池组成,负责全部 I/O 任务的分发与执行1)js语法必须会
2)我的学习和技术选型都要按部就班
能够看出个人思路,先能写,而后再追求更好的写法,好比面向对象。等团队水平到必定程度了,而且稳定的时候,能够考虑更加极致的函数式写法。
3)各类高级的JavaScript友好语言
JavaScript友好语言指的是可以使用其余语法实现,但最终编译成js的语言。自从Node.js出现后,这种黑科技层出不穷。好比比较有名的coffee、typescript、babel(es)等。
CoffeeScript虽然也是JavaScript友好语言,但其语法借鉴ruby,崇尚极简,对于类型和OO机制上仍是偏弱,并且这么多年也没发展起来,仍然是比较小众的活着。将来比例会愈来愈少的。
显然TypeScript会愈来愈好,TypeScript 的强大之处是要用过才知道的。
当下前端发展速度极快,以指数级的曲线增加。之前可能1年都不必定有一项新技术,如今可能每月都有。大前端,Node全栈,架构演进等等都在快速变化。能够说,前端越复杂,有越多的不肯定性,TypeScript的机会就越大。 4)再论面向对象
面向对象想用好也不容易的,并且js里有各类实现,真是让人眼花缭乱。
《Node.js in action》一书里说,Node.js 所针对的应用程序有一个专门的简称:DIRT。它表示数据密集型实时(data-intensive real-time)程序。由于 Node.js 自身在 I/O 上很是轻量,它善于将数据从一个管道混排或代理到另外一个管道上,这能在处理大量请求时持有不少开放的链接,而且只占用一小部份内存。它的设计目标是保证响应能力,跟浏览器同样。
这话不假,但在今天来看,DIRT 仍是范围小了。其实 DIRT 本质上说的 I/O 处理的都算,但随着大前端的发展,Node.js 已经再也不只是 I/O 处理相关,而是更加的“Node”!
nw.js/electron
、移动端 cordova
、HTML五、react-native
、weex
,硬件 ruff.io
等Vue
\ Angular
辅助开发,以及工程化演进过程(使用Gulp
/Webpack 构建 Web 开发工具)npm
上各类工具模块,包括各类前端预编译、构建工具 Grunt
/ Gulp
、脚手架,命令行工具,各类奇技淫巧等Node.js 应用场景很是丰富,好比 Node.js 能够开发操做系统,但通常我都不讲的,就算说了也没多大意义,难道你们真的会用吗?通常,我习惯将 Node.js 应用场景氛围7个部分。
1)初衷,server端,不想成了前端开发的基础设施 2)命令行辅助工具,甚至能够是运维 3)移动端:cordova,pc端:nw.js和electron 4)组件化,构建,代理 5)架构,先后端分离、api proxy 6)性能优化、反爬虫与爬虫 7) 全栈最便捷之路
Node.js是为异步而生的,它本身把复杂的事儿作了(高并发,低延时),交给用户的只是有点难用的Callback写法。也正是坦诚的将异步回调暴露出来,才有更好的流程控制方面的演进。也正是这些演进,让Node.js从DIRT(数据敏感实时应用)扩展到更多的应用场景,今天的Node.js已经不仅是能写后端的JavaScript,已经涵盖了全部涉及到开发的各个方面,而Node全栈更是热门种的热门。
直面问题才能有更好的解决方式,Node.js的异步是整个学习Node.js过程当中重中之重。
我整理了一张图,更直观一些。从09年到如今,8年多的时间里,整个Node.js社区作了大量尝试,其中曲折足足够写一本书的了。你们先简单了解一下。
结论:Promise是必须会的,那你为何不顺势而为呢?
推荐:使用Async函数 + Promise组合,以下图所示。
结论
下面让咱们看一下调用函数示例,Node.js 文档里最常采用下面这样的回调方式:
function(err, res) {
// process the error and result
}
复制代码
这里的 callback
指的是带有2个参数的函数:"err"和 "res"。语义上讲,非空的“err”至关于程序异常;而空的“err”至关于能够正常返回结果“res”,无任何异常。 b)EventEmitter
事件模块是 Node.js 内置的对观察者模式“发布/订阅”(publish/subscribe)的实现,经过EventEmitter
属性,提供了一个构造函数。该构造函数的实例具备 on
方法,能够用来监听指定事件,并触发回调函数。任意对象均可以发布指定事件,被 EventEmitter
实例的 on
方法监听到。
在node 6以后,能够直接使用require('events')
类
var EventEmitter = require('events')
var util = require('util')
var MyEmitter = function () {
}
util.inherits(MyEmitter, EventEmitter)
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
复制代码
和jquery、vue里的Event是很是相似的。并且前端本身也有EventEmitter。 c)如何更好的查Node.js文档
API是应用程序接口Application Programming Interface的简称。从Node.js异步原理,咱们能够知道,核心在于 Node.js SDK 中API调用,而后交由EventLoop(Libuv)去执行,因此咱们必定要熟悉Node.js的API操做。
Node.js的API都是异步的,同步的函数是奢求,要查API文档,在高并发场景下慎用。
笔者推荐使用 Dash 或 Zeal 查看离线文档,常常查看离线文档,对Api理解会深刻不少,比IDE辅助要好,能够有效避免离开IDE就不会写代码的窘境。 3)中流砥柱:Promise 回调地狱
Node.js 由于采用了错误优先的回调风格写法,致使sdk里导出都是回调函数。若是组合调用的话,就会特别痛苦,常常会出现回调里嵌套回调的问题,你们都很是厌烦这种写法,称之为Callback Hell,即回调地狱。一个经典的例子来自著名的Promise模块q文档里。
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
复制代码
这里只是作4步,嵌套了4层回调,若是更多步骤呢?不少新手浅尝辄止,到这儿就望而却步,粉转黑。这明显不够成熟,最起码你要看看它的应对解决方案吧! Node.js 约定全部Api都采用错误优先的回调方式,这部分场景都是你们直接调用接口,无太多变化。而Promise是对回调地狱的思考,或者说是改良方案。目前使用很是广泛,能够说是在async函数普及以前惟一一个通用性规范,甚至 Node.js 社区都在考虑 Promise 化,可见其影响之大。
Promise最先也是在commonjs社区提出来的,当时提出了不少规范。比较接受的是promise/A规范。后来人们在这个基础上,提出了promise/A+规范,也就是实际上如今的业内推行的规范。ES6 也是采用的这种规范。 Promise意味着[许愿|承诺]一个尚未完成的操做,但在将来会完成的。与Promise最主要的交互方法是经过将函数传入它的then方法从而获取得Promise最终的值或Promise最终最拒绝(reject)的缘由。要点有三个:
递归,每一个异步操做返回的都是promise对象
状态机:三种状态转换,只在promise对象内部能够控制,外部不能改变状态
全局异常处理 Async函数要点以下:
Async函数语义上很是好
Async不须要执行器,它自己具有执行能力,不像Generator须要co模块
Async函数的异常处理采用try/catch和Promise的错误处理,很是强大
Await接Promise,Promise自身就足够应对全部流程了,包括async函数没有纯并行处理机制,也能够采用Promise里的all和race来补齐
Await释放Promise的组合能力,外加co和Promise的then,几乎没有不支持的场景
通常,后端开发指的是 Web 应用开发中和视图渲染无关的部分,主要是和数据库交互为主的重业务型逻辑处理。但如今架构升级后,Node.js 承担了先后端分离重任以后,有了更多玩法。从带视图的传统Web应用和面向Api接口应用,到经过 RPC 调用封装对数据库的操做,到提供前端 Api 代理和网关,服务组装等,统称为后端开发,再也不是以往只有和数据库打交道的部分才算后端。这样,就可让前端工程师对开发过程可控,更好的进行调优和性能优化。 对 Node.js 来讲,一直没有在后端取得其合理的占有率,缘由是多方面的,暂列几条。
尽管如此,Node.js 仍是尽人皆知,卷入各类是非风口,也算是在大前端浪潮中大红大紫。缘由它的定位很是明确,补足以 JavaScript 为核心的全栈体系中服务器部分。开发也是人,可以同时掌握并精通多门语言的人毕竟很少,并且程序员的美德是“懒”,能使用 JavaScript 一门语言完成全部事儿,为何要学更多呢? 咱们能够根据框架的特性进行分类
框架名称 | 特性 | 点评 |
---|---|---|
Express | 简单、实用,路由中间件等五脏俱全 | 最著名的Web框架 |
Derby.js && Meteor | 同构 | 先后端都放到一块儿,模糊了开发便捷,看上去更简单,实际上上对开发来讲要求更高 |
Sails、Total | 面向其余语言,Ruby、PHP等 | 借鉴业界优秀实现,也是 Node.js 成熟的一个标志 |
MEAN.js | 面向架构 | 相似于脚手架,又指望同构,结果只是蹭了热点 |
Hapi和Restfy | 面向Api && 微服务 | 移动互联网时代Api的做用被放大,故而独立分类。尤为是对于微服务开发更是利器 |
ThinkJS | 面向新特性 | 借鉴ThinkPHP,并慢慢走出本身的一条路,对于Async函数等新特性支持,无出其右,新版v3.0是基于Koa v2.0的做为内核的 |
Koa | 专一于异步流程改进 | 下一代Web框架 |
Egg | 基于Koa,在开发上有极大便利 | 企业级Web开发框架 |
对于框架选型
Tips:我的学习求新,企业架构求稳,无非喜爱与场景而已 Web编程核心
异步流程控制(前面讲过了)
基本框架 Koa或Express,新手推荐Express,毕竟资料多,上手更容易。若是有必定经验,推荐Koa,其实这些都是为了了解Web编程原理,尤为是中间件机制理解。
数据库 mongodb或mysql都行,mongoose和Sequelize、bookshelf,TypeOrm等都很是不错。对于事物,不是Node.js的锅,是你选的数据库的问题。另一些偏门,想node连sqlserver等估计还不成熟,我是不会这样用的。
模板引擎, ejs,jade,nunjucks。理解原理最好。尤为是extend,include等高级用法,理解布局,复用的好处。其实先后端思路都是同样的。
Node 的书几乎都过期了,我该买哪本?
Node 用途那么多,我该从哪里学起?
Node Web 框架那么多,我该怎么选?