通过手动写一个Promise去理解其工作机制。
先写一个简单的promise函数方法:
const localTest = new Promise((resolve, reject)=>{
resolve("test")
},100)
localTest.then(res =>{
console.log(res);
})
可以得到结果
test
接下来我们开始手写一个promise去理解其原理。
promise中存在三种状态: resolve, pending, rejected
所以一开始我们需要建立一个Promise的类。
class WPromise {
status = PENDIND;
result = undefined;
reason = undefined;
constructor(excution){
const resolve = (result) =>{
if(this.status === PENDIND){
this.result = result;
this.status = RESOLVE;
}
};
const reject = (reason) =>{
if(this.status === PENDIND){
this.reason = reason;
this.status = REJECT;
}
};
try{
excution(resolve,reject);
}catch(error){
reject(error);
}
}
then(onResolved, onRejected) {
if(this.status=== RESOLVE) {
onResolved(this.resutl);
}
if (this.status === REJECT){
onRejected(this.reasion);
}
}
}
通过建立一个promise的类,我们可以直接调用,
const test = new WPromise((resolve, reject) =>{
setTimeout(() => {
resolve('this is a test');
}, 1000)
});
test.then((res) =>{
console.log(res);
})
会发现then方法并没有任何输出,是因为在promise方法和then方法在此时是同步操作,即使test方法运行后就直接运行了then方法,理论上我们应该等待test的结果并传送到then再执行then方法的。
为了实现这个方法,我们可以采用一个发布订阅模式来实现。
const RESOLVE = 'reslove';
const REJECT = 'rejected';
const PENDIND = 'pending';
class WPromise{
status = PENDIND;
result = undefined;
reason = undefined;
onResolvedArr = [];
onRejectedArr = [];
constructor(excution){
const resolve = (result) =>{
if(this.status === PENDIND){
this.result = result;
this.status = RESOLVE;
this.onResolvedArr.map((fn) => fn());
}
};
const reject = (reason) =>{
if(this.status === PENDIND){
this.reason = reason;
this.status = REJECT;
this.onRejectedArr.map,((fn) => fn());
}
};
try{
excution(resolve,reject);
}catch(error){
reject(error);
}
}
then(onResolved, onRejected){
if(this.status === RESOLVE){
setTimeout(()=>{
try{
onResolved(this.result);
handelePromise(result, newPromise, resolve, reject);
}catch(error){
reject(error);
}
},0);
}
if(this.status === REJECT){
setTimeout(()=>{
try {
onResolved(this.reason);
handelePromise(result, newPromise, resolve, reject);
} catch (error) {
reject(error);
}
})}
if(this.status === PENDIND){
try {
this.onResolvedArr.push(() => {
onResolved(this.result);
});
this.onRejectedArr.push(()=>{
onRejected(this.reason);
});
} catch (error) {
reject(error);
}
}
}
}
export default WPromise
通过以上的方法,我们就可以实现一个简单的promise的异步操纵
const WPromise = require("./wpromise");
const localTest = new WPromise((resolve, reject)=>{
resolve("test")
},100)
localTest.then(res =>{
console.log(res);
})
可以获得控制行输出test
但是如果我们想实现整一个流操作的话,发现并不能够实现流式操作,即是在then后面继续then下去。为此我们可以进一步去完善。
const RESOLVE = 'reslove';
const REJECT = 'rejected';
const PENDIND = 'pending';
const handelePromise = (result, newPromise, resolve, reject) => {
if(result === newPromise){
throw new Error('can not return oneself');
}
if(
(typeof result === 'object' && typeofresult !== null) ||
typeof result === 'function'
){
let lock = false;
try {
const then = result.then;
if(typeof then === 'function'){
then.call(
result,
(r) => {
if(lock) return;
this.handelePromise(r,newPromise,resolve,reject);
lock = true;
},
(e) => {
if(lock) return;
reject(e);
lock = true;
}
);
}else{
resolve(result);
}
} catch (error) {
reject(error);
}
}else{
resolve(result)
}
};
class WPromise{
status = PENDIND;
result = undefined;
reason = undefined;
onResolvedArr = [];
onRejectedArr = [];
constructor(excution){
const resolve = (result) =>{
if(this.status === PENDIND){
this.result = result;
this.status = RESOLVE;
this.onResolvedArr.map((fn) => fn());
}
};
const reject = (reason) =>{
if(this.status === PENDIND){
this.reason = reason;
this.status = REJECT;
this.onRejectedArr.map,((fn) => fn());
}
};
try{
excution(resolve,reject);
}catch(error){
reject(error);
}
}
then(onResolved, onRejected){
onResolved = typeof onResolved === 'function' ? onResolved : (data) => data;
onRejected = typeof onRejected === 'function' ? onRejected : (err) => {
throw new Error(err);
};
const newPromise = new WPromise((reslove, reject)=>{
if(this.status === RESOLVE){
setTimeout(()=>{
try{
onResolved(this.result);
handelePromise(result, newPromise, resolve, reject);
}catch(error){
reject(error);
}
},0);
}
if(this.status === REJECT){
setTimeout(()=>{
try {
onResolved(this.reason);
handelePromise(result, newPromise, resolve, reject);
} catch (error) {
reject(error);
}
},0);
}
if(this.status === PENDIND){
try {
this.onResolvedArr.push(() => {
onResolved(this.result);
});
this.onRejectedArr.push(()=>{
onRejected(this.reason);
});
} catch (error) {
reject(error);
}
}
});
return newPromise;
}
catch(onRejected){
return this.then(undefined,onRejected);
}
}
module.exports = WPromise;
通过以上的方法,我们通过对then得到的res进行判断,从而实现了流式操作。
当然上述只是理解层面,还有很多细节并没有完善,可以便于理解