Node.js(day5) (2)

增删改查
更多请参考官方文档:
https://mongoosejs.com/docs/guide.html
增:save()
查:findById() | find() | findOne()
删:findByIdAndRemove() | remove() | findOneAndRemove()
改:findByIdAndUpdate()| update() | findOneAndUpdate()

三、案例:使用MongoDB修改之前的案例

略,即使用mongodb来代替之前的db.json和fs模块。

四、promise对象 1.回调地狱

回调函数可以为我们返回异步操作的数据,但回调函数还是无法保证异步函数的执行顺序。比如我们有三个文件:a.txt、b.txt、c.txt。我们使用fs.readFile()按顺序来读取a.txt、b.txt、c.txt。
那我们就需要使用嵌套的写法才能实现自定义顺序异步操作:

var fs = require('fs'); fs.readFile('./a.txt','utf8',(err,data) => { if(err) return console.log(err); console.log(data); fs.readFile('./b.txt','utf8',(err2,data2) => { if(err) return console.log(err2); console.log(data2); fs.readFile('./c.txt','utf8',(err3,data3) => { if(err) return console.log(err3); console.log(data3); }); }); });

Node.js(day5)

对于这种层层嵌套的回调函数,我们一般称为“回调地狱”,首先我们发现这种回调函数不美观易错不好维护。所以es6出现了Promise对象,专门用来处理这种回调地狱问题。

2.Promise对象

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
我们可以看一下示意图:

Node.js(day5)

大致意思就是:

Promise对象以一个异步操作为参数,保存了其执行状态。

异步操作的失败与否决定了Promise的状态。

而每一个状态执行之后的返回值为Promise对象,这样就实现了顺序链式执行回调函数。
具体看如下实例:

var fs = require('fs'); //将异步操作封装为Promise对象 var q1 = new Promise((resoleve,reject) => { fs.readFile('./a.txt','utf8',(err,data) => { if(err){ reject(err); }else{ resoleve(data); } }); }); var q2 = new Promise((resoleve,reject) => { fs.readFile('./b.txt','utf8',(err,data) => { if(err){ reject(err); }else{ resoleve(data); } }); }); var q3 = new Promise((resoleve,reject) => { fs.readFile('./c.txt','utf8',(err,data) => { if(err){ reject(err); }else{ resoleve(data); } }); }); //利用Promise的链式特性决定异步操作的顺序:使用then方法执行异步操作 q1.then((data) => { console.log(data); return q2;//这句话的意思是返回的对象为q2,那么q1执行之后就是q2执行 },(err) => { console.log(err); }).then((data) => { console.log(data); return q3; },(err) => { console.log(err); }).then((data) => { console.log(data); },(err) => { console.log(err); });

then方法有两个回调函数参数,当Promise的状态为resolved是执行第一个回调函数,状态为rejected时执行第二个参数。

上面说then()执行异步操作有点问题,其实应该是new Promise()后就执行了,因为需要先判断异步操作状态。

使用return语句和then()方法就可以链式操作回调函数,还能决定顺序。(其实并没有改变执行顺序,但可以控制数据的输出顺序。)

上面Promise创建的方法可以进行封装让代码更简洁:

var fs = require('fs'); //将异步操作封装为Promise对象 function readFilePromise(filepath){ return new Promise((resoleve,reject) => { fs.readFile(filepath,'utf8',(err,data) => { if(err){ reject(err); }else{ resoleve(data); } }); }); } var q1 = readFilePromise('./a.txt'), q2 = readFilePromise('./b.txt'), q3 = readFilePromise('./c.txt'); //利用Promise的链式特性决定异步操作的顺序:使用then方法"执行"异步操作 q1.then((data) => { console.log(data); return q2;//这句话的意思是返回的对象为q2,那么q1执行之后就是q2执行 },(err) => { console.log(err); }).then((data) => { console.log(data); return q3; },(err) => { console.log(err); }).then((data) => { console.log(data); },(err) => { console.log(err); });

其实Jquery中的ajax的相关方法已经实现了Promise的相关方法,这里应用场景不再举例,更多可参考:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyjsp.html