Promise入门
标签:
JavaScript
一、生命周期
Promise生命周期中有三个状态
- 进行中(pending)
- 成功(resolved)
- 拒绝(rejected)
pending代表promise进入未处理(处理中)状态,一旦promise生命周期结束就会变为:resolved和rejected状态其中之一,resolved代表处理成功,rejected代表处理被拒绝;而且Promise一旦状态改变就不会变,promise改变状态的结果只有2种可能:
pending => resolved // 成功
pending => rejected // 失败
二、创建Promise
可以使用Promise构造函数创建Promise,构造函数接收2个参数:
- resolve() 处理成功下调用的返回函数
- reject() 处理拒绝下调用的返回函数
const fs = require('fs');
let handler = new Promise((resolve, reject) => {
fs.readFile('./order.js', {encoding: 'utf8'}, (err, contents) => {
// 当发生错误时,使用reject方法抛出错误
if (err) {
reject(err);
return;
}
// 当成功执行后,执行resolve方法
resolve(contents)
})
})
三、处理Promise
创建的Promise执行完且改变状态后,then() 方法会监听其状态处理结果,接收2个参数:
- 第一个参数接收的是 resolve() 处理成功函数的回调。
- 第二个参数接收的是 reject() 处理拒绝函数的回调。
// 接上面的handler方法
// 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
// 第一个参数是回调resolve方法 [可选]
// 第二个参数是回调reject方法 [可选]
handler.then(res => {
// success
console.log(res);
}, err => {
// error
console.log(err);
})
还有一个方法是 catch() 方法,这个方法是单独接收 reject() 拒绝函数的回调,结合 then() 方法,我们可以这样写:
handler.then(res => {
// success
console.log(res);
}).catch(err => {
// error
console.log(err);
})
四、链式Promise
当在promise链式中then()中触发return返回另外一个promise,只有当这个promise是成功执行了才会执行下一步promise链式操作,反之其中发生拒绝状态,那么下一个promise异步操作永远不会执行。
let p1 = Promise.resolve('p1');
let p2 = Promise.resolve('p2');
let p3 = Promise.reject('p3 is error');
let p4 = Promise.resolve('p4');
p1.then(res => {
console.log(res); // p1
return p2;
}).then(res => {
console.log(res); // p2
return p3;
}).then(res => {
console.log(res); // error 不会执行到这步
return p4;
}).then(res => {
console.log(res); // 不执行
}).catch(err => {
console.log(err); // 获取到p3错误,p3 is error
// 解释:因为p3返回的是错误状态,p4后面就不执行了
})
四、Generator与链式Promise结合
上面的链式操作非常不优雅,我们可以使用迭代器优化代码,如下:
let p1 = Promise.resolve('p1');
let p2 = Promise.resolve('p2');
let p3 = Promise.reject('p3 is error');
let p4 = Promise.resolve('p4');
function* handlerPromise() {
yield p1.then(res => { console.log(res) });
yield p2.then(res => { console.log(res) });
yield p3.catch(err => { console.log(err) });
yield p4.then(res => { console.log(res) });
}
let handler = handlerPromise();
handler.next().value;
handler.next().value;
handler.next().value;
handler.next().value;
/**
* 输出:
* p1
* p2
* p4
* p3 is error
*/
五、Promise.all()
Promise.all()方法可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。
// 情景一:promise都变为resolve状态
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
Promise.all([p1, p2]).then(res => {
console.log(res); // [1, 2]
})
// 情景二:promise其中变为reject状态
let p1 = Promise.resolve(1);
let p2 = Promise.reject(2);
Promise.all([p1, p2]).then(res => {
console.log(res); // not data...
}).catch(err => {
console.log(err) // 捕获到错误
})
六、Promise.race()
Promise.race()方法和Promise.all()方法接收的参数一样,接收一个可迭代对象,比如数组,唯一的区别就是,Promise.race()方法返回的是该传入的对象的第一个promise结束状态后的结果,简单来说就是传入的promise对象,谁最先得出返回结果(无论是resolve或reject),就输出谁。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 2000)
});
let p2 = Promise.reject(2);
Promise.race([p1, p2]).then(res => {
console.log(res);
}).catch(err => {
console.log(err); // 2
})
七、Promise优缺点
优点:
- Promise主要解决回调地狱问题
- 使得原本的多层级的嵌套代码,变成了链式调用
- 让代码更清晰,减少嵌套数
缺点:
- 无法取消Promise,一旦新建它就会立即执行,无法中途取消
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
- 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是处理中)
参考资料
- 《深入理解ES6》-第六章 Promise与异步编程
点击查看更多内容
6人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦