class Promise{
constructor(excutor){
this.value = '';
this.reason = '';
this.status = 'padding'
this.onFulfilledCallback = []
this.onRejectedCallback = []
let resolve = (value)=>{
/*2.这个判断是为了status不可逆 只能从 padding转化为 成功或者失败*/
if (this.status == 'padding') {
this.status = 'fulfilled'
this.value = value
/*3.当转态改变的时候依次执行队列里面储存的then函数里面对应的回调*/
this.onFulfilledCallback.forEach(fn=>{
fn()
})
}
};
let reject = (reason)=>{
/*2.这个判断是为了status不可逆 只能从 padding转化为 成功或者失败*/
if (this.status == 'padding') {
this.status = 'rejected'
this.reason = reason
/*3.当转态改变的时候依次执行队列里面储存的then函数里面对应的回调*/
this.onRejectedCallback.forEach(fn=>{
fn()
})
}
};
/*1. 当发生异常是捕获异常 */
try{
excutor(resolve,reject)
}catch (e){
reject(e)
}
}
then(onFulfilled,onRejected){
//4.防止使用者不传成功或失败回调函数,所以成功失败回调都给了默认回调函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : error => { throw error };
let newPromise;
if(this.status == 'fulfilled'){
return newPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{
try{
let x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject);
}catch (e){
reject(e)
}
})
})
}
if(this.status == 'rejected'){
return newPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{
try{
let x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject);
}catch (e){
reject(e)
}
})
})
}
if(this.status == 'padding'){
return newPromise = new Promise((resolve,reject)=> {
/*3.当excutor为异步的时候先把then方法里面的回调储存在失败或者成功的队列里面*/
// 一个promise可以then多次 ,等会改变状态后会让then中的函数执行
// promise.then((data)=>{
// console.log('res',data);
// },(err)=>{
// console.log(err);
// });
// promise.then((data)=>{
// console.log('res',data);
//},(err)=>{
// console.log(err);
//});
this.onFulfilledCallback.push(() => {
//这里可以写其他的代码对resolve做一层封装todo
setTimeout(()=> {
try {
let x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e)
}
})
})
this.onRejectedCallback.push(() => {
setTimeout(()=> {
try {
let x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e)
}
})
})
})
}
//4.保证链式调用 返回this 这样做虽然能链式调用但是 所有链式调用的回调函数都挂载到同一个对象上 且当后面的then方法执行
//的时候promise的状态已经确定会马上执行其对应的回调,并且参数都为this.value这一个值
//return this
}
catch(onRejected){
this.then(null,onRejected)
}
resolvePromise(newPromise,x,resolve,reject){
//2.3.1规范,避免循环引用
if (newPromise === x) {
return reject(new TypeError('Circular reference'));
}
//called变量主要是用来判断如果resolvePromise函数已经resolve或者reject了,那就不需要在执行下面的resolce或者reject。
//设置一个标志位,在执行resolve或者reject其中之一后,讲不能再执行resolve或者reject eg:resolve();reject()
let called = false;
if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) {
try{
let then = x.then;
if (typeof then === 'function') {
//2.3.3.3 如果 then 是一个函数,以x为this调用then函数,且第一个参数是resolve,第二个参数是reject
then.call(x, y => {
if (called) return;
called = true;
this.resolvePromise(newPromise, y, resolve, reject);
}, error => {
if (called) return;
called = true;
reject(error);
})
} else {
//2.3.3.4 如果 then不是一个函数,则 以x为值fulfill promise。
resolve(x);
}
}catch(e){
if (called) return;
called = true;
reject(e);
}
}else {
resolve(x)
}
}
}
// 执行测试用例需要用到的代码
Promise.deferred = function() {
let defer = {};
defer.promise = new Promise((resolve, reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
try {
module.exports = Promise
} catch (e) {}
// 1.npm i -g promises-aplus-tests
// 2.promises-aplus-tests mypromise.js
手写promise
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Promise标准了解一下 传送门1⃣️ 👉Promises/A+规范 传送门2⃣️ 👉阮一峰前辈ECMAScri...
- 1. promise要解决的问题: 脑筋急转弯:把牛关进冰箱里,要分几步? 很显然,这三个操作不能颠倒顺序,否则任...
- https://juejin.im/post/5b55c28ee51d45195a7139d6 扩展 Promis...
- 一、Promise.all() 核心思路: Promise.myAll()返回的肯定是一个promise对象,所以...
- 1. Promise A+ 规范 官方英文地址:https://promisesaplus.com/ 中文翻译可参...