作者:D827
起源:恒生 LIGHT 云社区
没有一个性能是看了源码后,还不会用的。所以看完本篇文章,心愿能帮忙你彻底把握 Promise。
Promise 的介绍
Promise 对象是 ES6 提供的实现异步的一个解决方案,它使得异步办法能够像同步办法那样返回值。
promise 是一个 构造函数 , 包裹(封装)一个 异步函数 (ajax; 定时器;数据库读取;fs 文件读取),当然它也能够包裹一个非异步函数。入参为两个 函数 :resolve、reject。胜利调用 resolve,并传递参数,失败调用 reject,并传递参数。应用.then 来作为 回调后果的解决 ,then 承受两个 函数参数,第一个参数承受正确的返回后果,第二个函数接管谬误的返回后果。
Promise 三种状态:pending、fullfilled/resolved、rejected
Promise 初始状态为 pending,通过 resolve 办法将状态批改为 fullfilled/resolved; 通过 reject 将状态批改为 rejected
promise 的长处:它可能实现链式调用,解决了回调实现异步导致的回调天堂问题。
promise 的毛病:
- 无奈监测进行状态、新建立刻执行且无奈勾销;
- 如果不设置回调函数,Promise 外部抛出的谬误,不会反馈到内部;
- 有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确。
Promise 的根本应用
function sleep(data){return new Promise((resolve,reject)=>{
// new Promise 包裹的能够是一个异步的代码,也能够是一个同步的代码
// 代码执行胜利
setTimeOut(()=>{
let result = null
if(1){resolve(result)
}else{reject(result)
}
},1000)
})
}
sleep(1000).then(v=>{// 正确返回解决},e=>{// 谬误返回解决}).then(v=>{}).then(v=>{})
……
.catch(e=>{// 错误处理})
自定义 Promise 须要留神的问题,及解答
-
promise 如何批改状态
通过调用 resolve、reject 批改状态
-
屡次调用 resolve、reject 能够批改状态吗
不能够,当从 pending 批改为 resolved 或者 rejected 后无奈再次批改为其余状态
-
promise 是先批改状态还是显示执行 then,以及什么时候失去数据
两种状况都可能呈现,当 promise 包裹的内容为异步时先指定 then 再批改状态,反之先批改状态再执行 then;
数据是在执行完回调后获取。
-
promise.then 返回一个 promise,这个返回的类型后果由谁决定
返回的为 promise,由返回的 promise 决定
返回为非 promise,则返回为 resolved
-
promise 如何串联多个操作工作
因为 promise.then 返回的是一个新的 Promise 对象,所以还能够调用 then,实现链式调用
-
promise 异样穿透
意思是不管有多少个 then,两头任意一个 then 呈现报错都会被 catch 捕捉
-
如何终止 promise 链
then 中任意一个出现异常;
在任意 then 中将 promise 的状态改为 pending。
Promise 的自定义
// 申明构造函数
function Promise(executor){
// 增加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 申明属性 回调存在多个状况
this.callbacks = [];
// 保留实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
// 判断状态 屡次调用 resolve、reject 不能够批改状态
if(self.PromiseState !== 'pending') return;
//1. 批改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象后果值 (promiseResult)
self.PromiseResult = data;
// 调用胜利的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {item.onResolved(data);
});
});
}
//reject 函数
function reject(data){
// 判断状态
if(self.PromiseState !== 'pending') return;
//1. 批改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象后果值 (promiseResult)
self.PromiseResult = data;
// 执行失败的回调
setTimeout(() => {
self.callbacks.forEach(item => {item.onRejected(data);
});
});
}
try{
// 同步调用『执行器函数』executor(resolve, reject);
}catch(e){
// 批改 promise 对象状态为『失败』reject(e);
}
}
// 增加 then 办法
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
// 判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {throw reason;}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
//value => {return value};
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type){
try{
// 获取回调函数的执行后果
let result = type(self.PromiseResult);
// 判断
if(result instanceof Promise){
// 如果是 Promise 类型的对象
result.then(v => {resolve(v);
}, r=>{reject(r);
})
}else{
// 后果的对象状态为『胜利』resolve(result);
}
}catch(e){reject(e);
}
}
// 调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){setTimeout(() => {callback(onResolved);
});
}
if(this.PromiseState === 'rejected'){setTimeout(() => {callback(onRejected);
});
}
// 判断 pending 状态
if(this.PromiseState === 'pending'){
// 异步状况下保留回调函数 在异步执行完结后执行回调函数
this.callbacks.push({onResolved: function(){callback(onResolved);
},
onRejected: function(){callback(onRejected);
}
});
}
})
}
// 增加 catch 办法
Promise.prototype.catch = function(onRejected){return this.then(undefined, onRejected);
}
// 增加 resolve 办法
Promise.resolve = function(value){
// 返回 promise 对象
return new Promise((resolve, reject) => {if(value instanceof Promise){
value.then(v=>{resolve(v);
}, r=>{reject(r);
})
}else{
// 状态设置为胜利
resolve(value);
}
});
}
// 增加 reject 办法
Promise.reject = function(reason){return new Promise((resolve, reject)=>{reject(reason);
});
}
// 增加 all 办法
Promise.all = function(promises){
// 返回后果为 promise 对象
return new Promise((resolve, reject) => {
// 申明变量
let count = 0;
let arr = [];
// 遍历
for(let i=0;i<promises.length;i++){
//
promises[i].then(v => {
// 得悉对象的状态是胜利
// 每个 promise 对象 都胜利
count++;
// 将以后 promise 对象胜利的后果 存入到数组中
arr[i] = v;
// 判断
if(count === promises.length){
// 批改状态
resolve(arr);
}
}, r => {reject(r);
});
}
});
}
// 增加 race 办法
Promise.race = function(promises){return new Promise((resolve, reject) => {for(let i=0;i<promises.length;i++){promises[i].then(v => {
// 批改返回对象的状态为『胜利』resolve(v);
},r=>{
// 批改返回对象的状态为『失败』reject(r);
})
}
});
}
心愿以上内容对你有所帮忙!
想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?
恒生 LIGHT 云社区,由恒生电子搭建的金融科技业余社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。
扫描下方小程序二维码,退出咱们!