为什么要用promise?
-
解决回调地狱
fs.readFile(__dirname + '/data/a.txt', (err, data)=>{ if(!err){ console.log(data.toString()); fs.readFile(__dirname + '/data/b.txt', (err, data)=>{ if(!err){ console.log(data.toString()); } fs.readFile(__dirname + '/data/cc.txt', (err, data)=>{ if(!err){ console.log(data.toString()); } }); }); } });
-
异步请求解决方案
概念
什么是Promise?
- promise,承诺。在代码中我们可以这么理解:此处我先许下个承诺,过了一定时间后我带给你一个结果。
- 在 Ecmascript 6 中体现出来就是一个容器对象, 一般用来封装一个异步操作
那么,在这一段时间中做什么?
- 我们可以进行异步操作;
比如请求网络数据、耗时运算、读写本地文件等
Promise的三种状态
异步操作是一个无法预测的事情,要么成功,要么失败
容器内部有三种状态
- Pending:Promise对象实例创建时候的初始状态
- Fulfilled :成功的状态
- Rejected :失败的状态
注意: 状态不可回退
读取文件实践
创建Promise对象 (一经创建,立即执行)
- 细节点1
当 Promise 对象内部的异步操作结果失败的时候,告诉 Promise 对象容器,该异步任务失败了, 其实就是将 Promise 内部的 Pending 状态改为 Rejected - 细节点2
Promise 对象内部的异步操作没有错误发生,证明成功了, 然后在这里将 Promise 内部的 Pending 状态改为 Resolved - 细节点3(错误处理)
在使用 Promise 做异步流程控制的时候,关于异常的处理可以通过在最后一个 then 之后设置一个 catch
然后指定一个失败处理函数, 该函数可以捕获前面所有的 Promise 对象本身以及 then 内部的任务错误
当前面任何一个发生异常,直接进入 catch,后续所有的 Promise 包括 then 不再执行
resolve 和 reject两个参数
resolve用来返回失败的结果
reject用来返回成功的结果
注意:resolve和reject只能传一个值,多个值要用对象或数组传输。
new Promise((resolve, reject)=>{
resolve(1, 2, 222, 333);
}).then((data1,data2)=>{
console.log(data1,data2);
});
运行结果:
三个文件异步读取
const fs = require('fs');
new Promise((resolve, reject)=>{
fs.readFile(__dirname + '/data/a.txt', (err, data)=>{
if(err){
reject(err);
}
resolve(data);
});
}).then((data)=>{
console.log(data.toString());
return new Promise((resolve, reject)=>{
fs.readFile(__dirname + '/data/b.txt', (err, data)=>{
if(err){
reject(err);
}
resolve(data);
});
});
}).then((data)=>{
console.log(data.toString());
return new Promise((resolve, reject)=>{
fs.readFile(__dirname + '/data/cc.txt', (err, data)=>{
if(err){
reject(err);
}
resolve(data);
});
});
}).then((data)=>{
console.log(data.toString());
});
三个文件异步读取优化
const fs = require('fs');
readFile(__dirname + '/data/b.txt').then((data)=>{
console.log(data.toString());
return readFile(__dirname + '/data/a.txt');
}).then((data)=>{
console.log(data.toString());
return readFile(__dirname + '/data/cc.txt');
}).then((data)=>{
console.log(data.toString());
});
function readFile(...args){
return new Promise((resolve, reject)=>{
fs.readFile(...args, (err, data)=>{
if(err){
reject(err);
}
resolve(data);
})
});
}
异常捕获
在链条最后加一个catch,一旦有一个地方错误,都会执行该catch
const fs = require('fs');
readFile(__dirname + '/data/b.txt').then((data)=>{
console.log(data.toString());
return readFile(__dirname + '/data/aa.txt');
}).then((data)=>{
console.log(data.toString());
return readFile(__dirname + '/data/cc.txt');
}).then((data)=>{
console.log(data.toString());
}).catch(err => {
console.log(err);
});
function readFile(...args){
return new Promise((resolve, reject)=>{
fs.readFile(...args, (err, data)=>{
if(err){
reject(err);
}
resolve(data);
})
});
}