Promise是ES6中用来结局回调地狱的问题的但是并不能帮我们减少代码量
- Promise是一个构造函数 new Promise() 得到一个Promise一个实例
- 在Promise上有两个函数分别是resolve(成功之后的回调函数)和reject(失败之后的回调函数)
- 在Promise构造函数的prototype属性上,有一个.then()方法,也就是只要是Promise构造函数创建的实例,都可以访问到.then()方法
- 如果Promise表示一个异步操作,每当我们new一个Promise的实例,这个实例就表示一个具体的异步操作
- 既然Promise创建的实例是一个异步操作那么这个异步操作的结果只能有两种状态
- 状态一:异步执行成功 需要在内部调用,成功的回调函数resolve 把结果返回给调用者
- 状态二:异步执行失败了 需要在内部调用,成功的回调函数reject把结果返回给调用者
- 由于Promise的实例是一个异步操作,所以拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,来把成功或者失败的结果返回给调用者
- 我们可以在new出来的Promise实例上,调用.then()方法【预先】为这个Promise一部操作,指定成功(resolve)和失败(reject)回调函数
实现原理:(以读取文件为例)
1 //这是一个具体的异步操作,其中使用function 指定一个具体的异步操作
2 var promise = new Promise(function () {
3 //这个function 内部写的就是具体的异步操作
4 })
5 //每当new一个Promise实例的时候,就会立即执行这个异步操作中的代码
6 //如果不想立即执行需要放在一个函数中调用才执行
7 function getFile(fpath) {
8 var promise = new Promise(function (resolve,reject) {
9 fs.readFile(fpath,'utf-8',function (err,data) {
10 if(err) {
11 //console.log(err.message)
12 reject(err)
13 return false
14 }
15 //console.log(data);
16 resolve(data)
17 })
18 });
19 return promise
20 }
21 var p = getFile(path).then(function (data) {
22 console.log(data)
23 },function (err) {
24 console.log(err.message)
25 })
回调地狱的写法(了解即可)
getFile(path.join(__dirname,'./file/1.txt')).then((data)=>{
console.log(data);
getFile(path.join(__dirname,'./file/2.txt')).then((data)=>{
console.log(data);
getFile(path.join(__dirname,'./file/3.txt')).then((data)=>{
console.log(data);
})
})
})
注意:回调嵌套只会降低效率,并且如果需要读取的文件太多,不好排错,在没有将代码执行完毕之前你永远不知道这段代码是在干什么
正确的写法:
//在上一个.then中返回一个新的promise实例,可以继续用下一个.then来处理
getFile('路径1').then(function (data) {
console.log(1,data);
return getFile('路径2')
}).then(function (data) {
console.log(2,data);
return getFile('路径3')
}).then(function (data) {
console.log(3,data);
})
如果执行失败了不想影响后续的promise的正常执行此时我们需要单独为每一个promise通过.then指定一下失败的回调
getFile(path).then(function (data) {
console.log(data)
return getFile(path)
},function (err) {
console.log(err.message)
return getFile(path)
}).then(function (data) {
console.log(data)
return getFile(path)
},function (err) {
console.log(err.message)
return getFile(path)
})
不管是正确的回调函数还是失败的回调函数都需要将下一个回调函数所需要的对象return出去
如果前面的失败了,则后面的就没有继续执行下去的意义,此时我们想实现一旦报错则立即终止所有的promise的执行;
//在promise的最后使用catch
.catch(function (err) {
//catch如果前面有任何的promise执行失败,则立即终止所有promise的执行并马上进入catch去处理promise中抛出异常
console.log('这是自己的处理方式:'+err.message)
})