为什么用promise?
1、支持链式调用,可以解决回调地狱问题
2、指定回调函数的方式更加灵活
可封装一个异步操作,获取其成功和失败的值
异步编程
- fs文件操作
- 数据库操作
- AJAX
- 定时器
Promise 关键问题----如何中断 Promise 链
<script>
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("ok");
},1000)
})
p.then(value=>{
console.log(111);
}).then(value=>{
console.log(2222);
}).then(value=>{
console.log(333333);
}).catch(reason=>{
console.warn(reason);
})
</script>
结果如图所示:
如果我们只想得到前两个的输出值,则有且仅有一种方法:添加一个等待状态(pending状态)的Promise
即:
<script>
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("ok");
},1000)
})
p.then(value=>{
console.log(111);
}).then(value=>{
console.log(2222);
return new Promise(()=>{}) //添加一个等待状态的Promise
}).then(value=>{
console.log(333333);
}).catch(reason=>{
console.warn(reason);
})
</script>
结果如图:
Promise 的自定义封装
<script src="./promise.js"></script>
<script>
let p = new Promise((resolve,reject)=>{
// resolve("ok");
reject('ggg')
// throw "error"
});
console.log(p);
p.then(value=>{
console.log(value);
},reason=>{
console.log(reason);
})
</script>
分别声明构造函数以及then方法
// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 保存实例对象的 this 值
const self = this;
// resolve函数
function resolve(data) {
// 判断状态
if(self.PromiseState !== 'pending') return;
// 改变对象状态 promisestate
self.PromiseState = 'fulfilled';
// 设置对象结果值 promiseresult
self.PromiseResult = data;
}
// reject函数
function reject(data) {
if(self.PromiseState !== 'pending') return;
// 改变对象状态 promisestate
self.PromiseState = 'rejected';
// 设置对象结果值 promiseresult
self.PromiseResult = data;
}
// throw功能实现
try {
// 同步调用[执行器函数]
executor(resolve, reject);
} catch (e) {
// 修改 promise 状态为失败
reject(e)
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
// 调用回调函数
if(this.PromiseState === "fulfilled"){
onResolved(this.PromiseResult);
}
if(this.PromiseState === "rejected"){
onRejected(this.PromiseResult);
}
}