Node.js不是一门语言也不是框架,他只是基于Google V8引擎的JavaScript运行时环境,同时结合Libuv扩展了JavaScript功能,使之支持io、fs等只有语言才有的特性,使得JavaScript可以同时具备DOM操做(浏览器)和I/O、文件读写、操做数据库(服务器端)等能力,是目前最简单的全栈式语言。前端
Node.js一般被用来开发低延迟的网络应用,也就是那些须要在服务器端环境和前端实时收集和交换数据的应用(API、即时聊天、微服务)。node
总结:Node.js是构建在JavaScript之上的,事件触发和异步的,专为数据密集型实时程序设计的。其目标是让并发编程更简单,,主要应用在以网络编程为主的 I/O 密集型应用。他是开源的,跨平台,而且高效(尤为是 I/O 处理)react
下面是一张 Node.js 早期的架构图,来自 Node.js 之父 Ryan Dahl 的演讲稿,在今天依然不过期,它简要的介绍了 Node.js 是基于 Chrome V8引擎构建的,由事件循环(Event Loop)分发 I/O 任务,最终工做线程(Work Thread)将任务丢到线程池(Thread Pool)里去执行,而事件循环只要等待执行结果就能够了。git
核心概念github
梳理一下数据库
核心express
libuv
由事件循环和线程池组成,负责全部 I/O 任务的分发与执行在解决并发问题上,异步是最好的解决方案,能够拿排队和叫号机来理解npm
Node.js简称 数据密集型实时程序(DIRT)。由于Node.js自身在I/O 上很是轻量,它善于将数据从一个管道混排或代理到另外一个官道上,这能在处理大量请求时持有不少开放的链接,而且只占用一小部份内存。它的设计目标是保证影响能力,跟浏览器同样。编程
Node.js使用场景主要分为4大类:react-native
nw.js/electron
、移动端 cordova
、HTML五、react-native
、weex
,硬件 ruff.io
等Vue
\ Angular
辅助开发,以及工程化演进过程(使用Gulp
/Webpack 构建 Web 开发工具)npm
上各类工具模块,包括各类前端预编译、构建工具 Grunt
/ Gulp
、脚手架,命令行工具,各类奇技淫巧等Node.js是为异步而生的,他把复杂的事情都给作了(高并发,低延时),交给用户的只是有点难用的Callback写法。
直面问题才能有更好的解决方式,Node.js的异步是整个学习Node.js过程当中的重中之重。
a)Error-first Callback 定义错误优先的回调写法只须要注意2条规则便可:
b)EventEmitter
事件模块是 Node.js 内置的对观察者模式“发布/订阅”(publish/subscribe)的实现,经过EventEmitter
属性,提供了一个构造函数。该构造函数的实例具备 on
方法,能够用来监听指定事件,并触发回调函数。任意对象均可以发布指定事件,被 EventEmitter
实例的 on
方法监听到。
Node.js的API都是异步的,同步的函数是奢求,要查API文档,在高并发场景下慎用。
回调地狱
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 }); }); }); });
Promise意味着[许愿|承诺]一个尚未完成的操做,但在将来会完成的。与Promise最主要的交互方法是经过将函数传入它的then方法从而获取得Promise最终的值或Promise最终最拒绝(reject)的缘由。要点有三个:
1)定义
var promise = new Promise(function(resolve, reject) { // do a thing, possibly async, then… if (/* everything turned out fine */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } });
每一个Promise定义都是同样的,在构造函数里传入一个匿名函数,参数是 resolve 和 reject,分别表明成功和失败时候的处理。
2)调用
promise.then(function(text){ console.log(text)// Stuff worked! return Promise.reject(new Error('我是故意的')) }).catch(function(err){ console.log(err) })
它的主要交互方式是经过then函数,若是Promise成功执行resolve了,那么它就会将resolve的值传给最近的then函数,做为它的then函数的参数。若是出错reject,那就交给catch来捕获异常就行了。
Promise 的最大优点是标准化,各种异步工具库都按照统一规范实现,即便是async幻术也能够无缝集成。因此用 Promise 封装API通用性强,用起来简单,学习成本低。在async幻术普及以前,绝大部分应用都是采用 Promise来作异步流程控制的,因此掌握 Promise是Node.js学习必需要会的。
Async/Await是异步操做的终极解决方案,Koa 2在node 7.6发布以后,立马发布了正式版本,而且推荐使用async函数来编写Koa中间件。
这里给出一段Koa 2应用里的一段代码
exports.list = async (ctx, next) => { try { let students = await Student.getAllAsync(); await ctx.render('students/index', { students : students }) } catch (err) { return ctx.api_error(err); } };
它作了3件事儿
4.1 正常写法
const pkgConf = require('pkg-conf'); async function main(){ const config = await pkgConf('unicorn'); console.log(config.rainbow); //=> true } main();
变态写法
const pkgConf = require('pkg-conf'); (async () => { const config = await pkgConf('unicorn'); console.log(config.rainbow); //=> true })();
4.2 await + Promise
const Promise = require('bluebird'); const fs = Promise.promisifyAll(require("fs")); async function main(){ const contents = await fs.readFileAsync("myfile.js", "utf8") console.log(contents); } main();
4.3 await + co + generator
const co = require('co'); const Promise = require('bluebird'); const fs = Promise.promisifyAll(require("fs")); async function main(){ const contents = co(function* () { var result = yield fs.readFileAsync("myfile.js", "utf8") return result; }) console.log(contents); } main();
由上面3中基本用法能够推出Async函数要点以下:
小结
这部分共讲了4个小点,都是极其直接的必须掌握的知识点。
这里有一个练手的项目,感兴趣的同窗能够自行Download,相信会有所收获:https://github.com/oceanMin/cms