ECMAScript 6 新增的 Promise,可以通过 new 操作符来实例化一个期约实例,Promise 异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 最近尝试手写一个简单 Promise,也可以说是一个残缺版的 Promise,因为这里并没有实现 then 之后的进一步返回的一个新的 Promise(其实也是我现在还没想明白这里如何实现),也没有 finally 等这一个功能。只是简单的写了下我理解的最基本的实现而已。
class Promise {
constructor(fn) {
this.state = 0;
this.value = null;
this.deferreds = [];
doResolve(fn, this);
}
then(onFulfilled, onRejected) {
handle(this, { onFulfilled, onRejected });
}
catch(onRejected) {
handle(this, { onRejected });
}
}
function doResolve(fn, promise) {
try {
fn((result) => {
resolve(promise, result);
}, (reason) => {
reject(promise, reason);
});
} catch (error) {
reject(promise, error);
}
}
function resolve(promise, result) {
if (promise.state !== 0) {
return;
}
promise.state = 1;
promise.value = result;
finale(promise);
}
function reject(promise, reason) {
if (promise.state !== 0) {
return;
}
promise.state = 2;
promise.value = reason;
finale(promise);
}
function finale(promise) {
promise.deferreds.forEach((_promise) => {
if (promise.state === 1) {
_promise.onFulfilled(promise.value);
} else {
_promise.onRejected(promise.value);
}
});
promise.deferreds = [];
}
function handle(promise, deferred) {
if (promise.state === 0) {
promise.deferreds.push(deferred);
return;
}
handleResolved(promise, deferred);
}
function handleResolved(promise, deferred) {
const thenFn = promise.state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (!thenFn) {
if (promise.state === 1) {
resolve(deferred.promise, promise.value);
} else {
reject(deferred.promise, promise.value);
}
return;
}
let thenRes = null;
try {
thenRes = thenFn(promise.value);
} catch (error) {
thenRes = error;
}
}