什么是 Promise
将异步回调嵌套的代码变成链式调用的一种方法。
原理上分析:
一个 Promise 必处于以下状态之一:
- pending: 未决议 // 初始值
- resolved: 已解决
- rejected: 已失败
pending 状态下可以敲定为 resolved / rejected,只能敲定一次,之后不再改变。
Promise 接受一个执行者函数,会同步调用它,并交给个他两个决议的方法(resolved、rejected)执行者函数内部必须明确的调用其中一个。决议之后,就清空 then 添加的对应状态的任务列表(对应 resolved, rejected 状态),这是 Promise 做到异步回调 ”承上启下” 的重要一步。
每一个 then 在调用时就会返回一个默认的 Promise 实例(这支持了链式调用 then().then()
),该 Promise 的决议值是在 then 接受的 onResolved / onRejected 中选择一个调用并求值,选择哪个就由上层的 Promise 的决议状态决定,上层为 fulfilled 则调用 onResolved,为 rejected 则调用 onRejected;到此为止,还不能直接 resolve 回调的返回值,如果这个返回值还是 Promise 的话,就需要递归继续求值,直到值为非 Promise。
自实现Promise
建议仔细阅读这篇文章:史上最最最详细的手写Promise教程
以下是我的实现:没有满足 PromiseA+规范 中的所有细节,但用来理解原理足够了。
/**
* Promise State: pending, resolved, rejected
*
* 使用方法:
* new Promise((resolve, reject) => { // resolve/reject })
* .then(() => {}, () => {})
* .catch(e => { ... })
*
*/
class MyPromise {
constructor(excuter) {
this.state = "pending";
this.value = undefined;
this.reason = undefined;
this.onResolvedList = [];
this.onRejectedList = [];
const resolve = (value) => {
if (this.state === "pending") {
this.state = "resolved";
this.value = value;
this.onResolvedList.forEach(cb => {
cb(this.value);
});
}
};
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.reason = reason;
this.onRejectedList.forEach(cb => {
cb(this.reason);
});
}
};
try {
excuter(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onResolved, onRejected) {
return new MyPromise((resolve, reject) => {
onResolved = typeof onResolved === "function" ? onResolved : value => value;
onRejected = typeof onRejected === "function" ? onRejected : (reason) => {
throw reason;
};
const _onResolved = () => {
setTimeout(() => {
try {
let x = onResolved(this.value);
this.handlePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
});
};
const _onRejected = () => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
this.handlePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
});
};
if (this.state === "pending") {
this.onResolvedList.push(() => _onResolved());
this.onRejectedList.push(() => _onRejected());
}
if (this.state === "resolved") _onResolved();
if (this.state === "rejected") _onRejected();
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
/**
* if x is Promise
* x.then getValue
*
* if x not Proimse
* return x
*/
handlePromise(x, resolve, reject) {
let called = false;
try {
if (x !== undefined && x !== null && typeof x.then === "function") {
if (called) return;
called = true;
x.then(v => {
// maybe v also promise
setTimeout(() => {
this.handlePromise(v, resolve, reject);
});
}, (e) => {
if (called) return;
called = true;
reject(e);
});
} else {
if (called) return;
called = true;
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
}
}
// test
let p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("delay 100ms p1");
}, 100);
}).then(v => {
console.log("then recvie value: ", v);
return new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("delay 1000ms p1.then");
}, 1000);
});
}).then((v) => {
console.log("then recvie value: ", v);
throw new Error("custom error");
}).catch(e => {
console.log("cactch error: ", e);
});
复制代码
其他实现
Promise.reject 实现
class MyPromise {
// 省略...
reject(reason) {
return new MyPromise((resolve, reject) => {
rejected(reason);
});
}
}
复制代码
Promise.resolve 实现
class MyPromise {
// 省略...
resolve(value) {
return new MyPromise((resolve, reject) => {
resolve(value);
});
}
}
复制代码
Promise.catch 实现
class MyPromise {
// 省略...
catch(onRejected) {
this.then(null, onRejected);
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END