Node.js的异步是整个学习Node.js过程当中重中之重。前端
1)异步流程控制学习重点vue
2)Api写法:Error-first Callback 和 EventEmitternode
3)中流砥柱:Promisejquery
4)终极解决方案:Async/Awaitgit
.Node.js SDK里callback写法必须会的。github
Node.js学习重点: Async函数与Promisenpm
1.中流砥柱:Promiseapi
2.终极解决方案:Async/Awaitpromise
定义错误有限的回调写法只须要注意2条规则便可:并发
下面让咱们看一下调用函数示例,Node.js文档例最常采用下面这样的回调方式:
function(err,res){ //process the error and result }
这里的 callback 指的是带有2个参数的函数:“err”和“res” 。语义上讲,非空的"err"至关于程序异常;而空的“err”至关于能够正常返回结果“res”,无任何异常。
事件模块是 Node.js内置的对观察者模式“发布/订阅”(publish/subscribe)的实现,经过 EventEmitter属性,提供了一个构造函数。该构造函数的实例具备 on 方法,能够用来监听指定事件,并触发回调函数。任意对象均可以发布指定事件,被 EventEmitter 实例的 on方法监听到。
在node6以后,能够直接使用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。
API 是应用程序接口 Application Programming interface的简称。从Node.js异步原理,咱们能够知道,核心在于Node.js SDK中API调用,而后交由EventLoop(Libuv)去执行,因此咱们必定要熟悉Node.js的API操做。
Node.js的API都是异步的,同步的函数是奢求,要查API文档,在高并发场景下慎用。
笔者推荐使用 Desh和 Zeal查看离线文档,对api理解会深刻不少,比IDE辅助要好,能够有效避免离开IDE就不会写代码的窘境。
回调地狱
Node.js由于采用了错误优先的回调风格写法,致使sdk里导出都是回调函数,就会特别痛苦,常常会出现回调里嵌套回调的问题,你们都很是厌烦这种写法,称之为 Callback Hell,即回调地狱。一个经典的例子来自著名的Promise模块 q 文档里。
step1(function(value1){ step2(value1,function(value2){ step3(value2,function(value3){ step4(value3,function(){ // Do something with value4 }); }); }); });
这里只是作4步,嵌套了4层回调,若是更多步骤呢?不少新手浅尝辄止,到这儿就望而却步,粉转黑。这明显不够成熟,起码你要看看它的对应解决方案吧!
Promise最先也是在commonjs社区提出来的,当时提出了不少规范。比较接受的是promise/A规范。后来人们在这个基础上,提出了promise/A+规范,也就是实际上如今的业内推行的规范。ES6 也是采用的这种规范。
Promise意味着[许愿|承诺]一个尚未完成的操做,但在将来会完成的。与Promise最主要的交互方法是经过将函数传入它的then方法从而获取得Promise最终的值或Promise最终拒绝(reject)的缘由。要点有三个:
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,分别表明成功和失败时候的处理。
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学习过程当中必需要掌握的重中之重。
Bluebird是 Node.js 世界里性能最好的Promise/a+规范的实现模块,Api很是齐全,功能强大,是原生Promise外的不二选择。
好处以下:
在学习Node.js过程当中,对于Promise了解多深刻都不过度。
推荐学习资料
Async/Await是异步操做的终
极解决方案,Koa 2在node 7.6发布以后,立马发布了正式版本,而且推荐使用async函数来编写Koa中间件。
这里给出一段Koa2应用里的一段代码:
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件事儿
是否是很是简单,如今Eggjs里也都是这样同步的代码。
const pkgConf = require('pkg-conf') async function main(){ const config = await pkgConf('unicorn'); console.log(config.ranbow); //true } main()
变态写法:
const pkgConf = require('pkg-conf'); (async ()=> { const config = await pkgConf('unicorn') console.log(config.ranbow) //true })()
const Promise = require('bluedbird'); const fs = Promise.promisifyAll(require("fs")); async function main(){ const contents = await fs.readFileAsync("myfile.js","utf8") console.log(contents) } main()
const co = require('co') const Promise = require('bluedbird') const fs = Promise.promisifyAll(require("fs")) async function mian(){ const contents = co(function* () { var result = yield fs.readFileAsync("myfile.js","utf8") return result; }) console.log(contents) } main()
要点:
由上面3种基本用法能够推出Async 函数要点以下:
这部分共讲了4个小点,都是极其直接的必须掌握的知识点。
先用明白,而后再去阅读Node.js源码,而后探寻libuv并发机制。不少人买了朴大的《深刻浅出Node.js》一书,看了以后仍是不太会用,不是书写的很差,而是步骤不对。
迷茫时学习Node.js最好的方法
Node.js 编写的包管理器 npm 已成为开源包管理了领域最好的生态,直接到2017年10月份,有模块超过47万,每周下载量超过32亿次,每月有超过700万开发者使用npm。如今早已经超过60万个模块了。
这里就不一一举例了,给出一个迷茫时学习Node.js最好的方法吧!
"天天看10个npm模块"
对于学习Node.js迷茫的人来讲,这是最好的方式,当你不知道如何作的时候,就要向前(钱)看,你要知道积累哪些技能对之后有好处。对于学习Node.js必经之路,必定是要掌握不少模块用法,并从中汲取技巧、思路、设计思想的。与其不知道学什么,为何不天天积累几个技巧呢?
推荐一个repo即 https://github.com/parro-it/awesome-micro-npm-packages 小型库集合,一天看十个不是梦!
更多讨论 https://zhuanlan.zhihu.com/p/29625882
此为学习node的学习笔记,为了本身学习查阅,转自狼叔的教程,若是侵权请联系我删除
阅读原文