Promise 是异步编程的的最终结果,Promise 有三种状态: pending、fulfilled、rejected。只有异步操作的结果可以决定当前是哪一种状态,其它任何操作都无法改变。与之进行交互的方式主要是 then 方法,该方法注册了两个回调函数,用于接收 Promise 的终值或 promise 不能执行的原因。 当 then 中的回调函数不是函数的时候,会忽略当前 then 方法,使用前一个 then 中的值,如果 then 中的回调函数没有返回值,则下一个 then 的值默认 undefined,每个 then 只可能使用前一个 then 的返回值,并且调用次数不能超过一次。
Promise 的设计局限性造成了一个让人很容易中招的陷阱,那就是 Promise 链中的错误很容易被无意中默默忽略掉。
// 首先定义 Promise 的三个状态
const PENDING = "pending";
const RESOVLED = "resolved";
const REJECTED = "rejected";
/*
*创建一个 Promise 函数,接受一个函数参数
*开始时promise状态为 pending,value 值用来保存 resolve 或 reject 中传入的值
*CallBacks 用来保存 then 中的回调函数
*/
function Promise(fn) {
const that = this;
that.state = PENDING;
that.value = null;
that.resolveCallBacks = [];
that.rejectedCallBacks = [];
// 执行 fn 函数
try {
fn(resolve, reject)
} catch(err) {
reject(err);
}
// fn 中的 resolve, reject 分别是两个函数
function resolve(value) {
// 首先判断状态是否为 pending, 只有状态为 pending 时才能改变状态
if (that.state == PENDING) {
that.state = RESOLVED;
that.value = value;
// 执行 then 中的回调函数
that.resolveCallBacks.map(cb => (that.value = cb(that.value)))
}
}
function reject(value) {
if (that.state == PENDING) {
that.state = REJECTED;
that.value = value;
that.rejectCallBacks.map(cb => (that.value = cb(that.value)))
}
}
}
// 原型上的 then 方法
Promise.prototype.then = function(onFulfilled, onRejected) {
const that = this;
// 需要判断传入的参数是否为函数,如果不是函数需要创建一个函数赋值给对应参数,同时实现透传,也就开头所说的传入不是函数的问题
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected == 'function' ? onRejected : v => { throw v }
switch(that.state) {
case PENDING:
that.resolveCallBacks.push(onFulfilled);
that.rejectCallBacks.push(onRejected);
break;
case RESLOVED:
that.value = onFulfilled(that.value);
break;
case REJECTED:
that.value = onRejeted(that.value);
break;
defalut:
break;
}
return that;
}
// test
new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 10)
}).then(res => {
console.log(res) // 1
return 2;
}).then(res => {
console.log(res); // 2
})