【实现】Promise
很多时候,我们这样使用promise
let p = new Promise((resolve, reject) => {
if (1 < 2) { //判断条件
resolve(1);
} else {
reject(2);
}
})
p
.then(val => {console.log(val);})
.catch(err => {console.log(err)});
1.声明
所以我们需要声明一个类 Promise,它的参数((resolve, reject) => {})是一个表达式 executor
class RePromise{
constructor (executor) {
let resolve = () => {};
let reject = () => {};
executor (resolve, reject);
}
}
2.基本状态
promise的三种基本状态:pending,fulfilled,rejected
class RePromise{
constructor (executor) {
this.state = 'pending';
this.value = null;
this.reason = null;
let resolve = (value) => {
this.state === 'pending' ? this.state = 'fulfilled' : '';
this.value = value;
};
let reject = (reason) => {
this.state === 'pending' ? this.state = 'rejected' : '';
this.reason = reason;
};
try {
executor (resolve, reject);
} catch (err) {
reject(err);
}
}
}
3.then catch
class RePromise{
constructor (executor) {
this.state = 'pending';
this.value = null;
this.reason = null;
this.onResolvedCallback = [];
this.onRejectedCallback = [];
let resolve = (value) => {
this.state === 'pending' ? this.state = 'fulfilled' : '';
this.value = value;
};
let reject = (reason) => {
this.state === 'pending' ? this.state = 'rejected' : '';
this.reason = reason;
};
try {
executor (resolve, reject);
} catch (err) {
reject(err);
}
}
then (onFulfilled,onRejected) {
if (this.state === 'fulfilled') onFulfilled(this.value);
this.catch(onRejected);
return this;
}
catch (onRejected) {
if (this.state === 'rejected') onRejected(this.reason);
}
}
4.异步
使用 onResolvedCallback onRejectedCallback 暂存then或者catch的函数参数,待执行完成后调用
class RePromise{
constructor (executor) {
console.log(123123)
this.state = 'pending';
this.value = null;
this.reason = null;
this.onResolvedCallback = [];
this.onRejectedCallback = [];
let resolve = (value) => {
this.state === 'pending' ? this.state = 'fulfilled' : '';
this.value = value;
this.onResolvedCallback.forEach(fn => fn());
};
let reject = (reason) => {
this.state === 'pending' ? this.state = 'rejected' : '';
this.reason = reason;
this.onRejectedCallback.forEach(fn => fn());
};
try {
executor (resolve, reject);
} catch (err) {
reject(err);
}
}
then (onFulfilled,onRejected) {
if (this.state === 'fulfilled') onFulfilled(this.value);
if (this.state === 'pending') {
this.onResolvedCallback.push(()=> {onFulfilled(this.value)});
}
this.catch(onRejected);
return this;
}
catch (onRejected) {
if (this.state === 'rejected') onRejected(this.reason);
if (this.state === 'pending') {
this.onRejectedCallback.push(()=> {onRejected(this.value)});
}
}
}
let promise = new RePromise((resolve, reject) => {
setTimeout(()=> {
resolve(2);
}, 2000)
})
promise
.then(val => {console.log('then1',val);})
.catch(err => {console.log('catch',err)});
5.链式调用
then方法,注意这几种可能:
- return promise:resolve值传递给下一个then
- return 函数:return值传递
- 表达式:执行
function resolvePromise(promise2, x, resolve, reject){
if (x === promise2) reject('自身循环');
try {
if (typeof x === 'object' || typeof x === 'function') {
let then = x.then;
// x是promise
if (then && typeof then === 'function') {
x.then(
val => resolvePromise(promise2, val, resolve, reject),
err => {reject(err)}
);
} else { //x为普通函数
resolve(x);
}
} else { // x为普通值
resolve(x);
}
} catch (err) {
reject(err);
}
}
class RePromise{
constructor (executor) {
this.state = 'pending';
this.value = null;
this.reason = null;
this.onResolvedCallback = [];
this.onRejectedCallback = [];
let resolve = (value) => {
this.state === 'pending' ? this.state = 'fulfilled' : '';
this.value = value;
this.onResolvedCallback.forEach(fn => fn());
};
let reject = (reason) => {
this.state === 'pending' ? this.state = 'rejected' : '';
this.reason = reason;
this.onRejectedCallback.forEach(fn => fn());
};
try {
executor (resolve, reject);
} catch (err) {
reject(err);
}
}
then (onFulfilled,onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err};
let promise2 = new RePromise((resolve, reject) => {
if (this.state === 'fulfilled') {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
}
if (this.state === 'reject') {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
resolvePromise(promise2, err, resolve, reject);
}
}
if (this.state === 'pending') {
this.onResolvedCallback.push(()=> {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
});
this.onRejectedCallback.push(()=> {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
});
}
})
return promise2;
}
catch (onRejected) {
if (this.state === 'rejected') onRejected(this.reason);
if (this.state === 'pending') {
this.onRejectedCallback.push(()=> {onRejected(this.value)});
}
}
}
let promise = new RePromise((resolve, reject) => {
setTimeout(()=> {
resolve(2);
}, 2000)
})
promise
.then(val => {return new RePromise((resolve, reject)=>{resolve(123)})}, err=> console.log('err',err))
.then(val => {return val+1}, err=> console.log('err',err))
.then(val => console.log('then2', val), err=> console.log('err',err))
.catch(err => {console.log('catch',err)})
😊