前言:可能存在阐述不准确之处,欢迎指正~
Promise在long time ago就活跃于Javascript社区,受到开发者欢迎,只不过到近几年才被纳入ECMA规范。
我们为什么要使用Promsie?
因为:
我们不希望,过了几个月之后,代码只有上帝才看得懂;
我们不希望,回调代码越写越往右,只能换更大的显示器看;
我们希望,哪怕过了很久,代码依旧逻辑清晰,看懂不费吹灰之力;
我们希望,能够用自己的双手,控制住异步流的动向,就像同步代码一样;
有逼格...
(欢迎补充)
话不多说,上源码(采用es6/es7, 创建一个Commitment类模仿Promise)::
class Commitment {
constructor (executor) {
this.status = "pending";
this.value = void(0);
this.reason = void(0);
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (value instanceof Promise) {
return value.then(resolve, reject)
}
setTimeout(() => {
if (this.status === "pending") {
this.status = "resolved";
this.value = value;
this.onResolvedCallbacks.forEach(cb => cb(value));
}
})
}
const reject = (reason) => {
setTimeout(() => {
if (this.status === "pending") {
this.status = "rejected";
this.reason = reason;
this.onRejectedCallbacks.forEach(cb => cb(reason));
}
})
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : reason => {
throw reason
};
const resolveCommitment = (Commitment2, x, resolve, reject) => {
if (Commitment2 === x) {
return reject(new TypeError("A promise cannot be resolved with itself"))
}
let then, called;
if (x !== null && (typeof x === "object" || typeof x === "function")) {
try {
then = x.then;
if (typeof then === "function") {
then.call(x, y => {
if (called) return
called = true;
resolveCommitment(Commitment2, y, resolve, reject);
}, r => {
if (called) return
called = true;
reject(r)
})
} else {
resolve(x)
}
} catch (e) {
if (called) return
called = true;
reject(e)
}
} else {
resolve(x)
}
}
let Commitment2, x;
if (this.status === "resolved") {
Commitment2 = new Commitment((resolve, reject) => {
setTimeout(() => {
try {
x = onFulfilled(this.value);
resolveCommitment(Commitment2, x, resolve, reject)
} catch (e) {
reject(e)
}
});
})
}
if (this.status === "rejected") {
Commitment2 = new Commitment((resolve, reject) => {
setTimeout(() => {
try {
x = onRejected(this.reason);
resolveCommitment(Commitment2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
if (this.status === "pending") {
Commitment2 = new Commitment((resolve, reject) => {
this.onResolvedCallbacks.push((value)=> {
try {
x = onFulfilled(value);
resolveCommitment(Commitment2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
this.onRejectedCallbacks.push((reason) => {
try {
x = onRejected(reason);
resolveCommitment(Commitment2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
return Commitment2
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。