JavaScript
Promise 源码实现
Promise/A+规范 Promise 规范有 Promise/A Promise/B Promise/C Promise/D Promise/A+是 Promise/A 的升级版本 Promise 有 3 个状态:等待态(Pending)、执行态(Fulfilled)、拒绝态(Rejected) then 方法可以被一个 promise 调用多次,then 方法必须返回一个 promise 等…
Promise/A+规范 Promise 规范有 Promise/A Promise/B Promise/C Promise/D Promise/A+是 Promise/A 的升级版本 Promise 有 3 个状态:等待态(Pending)、执行态(Fulfilled)、拒绝态(Rejected) then 方法可以被一个 promise 调用多次,then 方法必须返回一个 promise 等…
等待态(Pending)可以迁移到执行态(Fulfilled)或者拒绝态(Rejected)
执行态(Fulfilled)不可迁移到其他任务状态,必须拥有不可变的终值
拒绝态(Rejected)不可迁移到其他任务状态,必须拥有一个不可变的据因
如果对 Promise 方法不熟悉,可以看阮一峰老师教程
function PromiseCopy(fn) {
// 定义一个then,用于把then的回调函数,是一个函数
this.then = (cb) => {
this.cb = cb;
};
// 定义一个resolve,是一个函数,用于执行then中回调函数
this.resolve = (data) => {
this.cb(data);
};
// 把this.resolve作为fn回调函数
fn(this.resolve);
}
var promise = new PromiseCopy((resolve) => {
setTimeout(() => {
resolve('hello world');
}, 1000);
});
promise.then((result) => {
console.log(result);
});
switch (_status) {
// 当状态为PENDING,将then方法回调函数加入执行队列
case PENDING:
this._fulfilledQueues.push(fulfilled);
this._rejcetedQueues.push(rejected);
break;
// 如果是FULFILLED,执行成功时执行的回调函数
case FULFILLED:
fulfilled(_value);
break;
// 如果是REJECTED,执行失败时执行的回调函数
case REJECTED:
rejected(_value);
break;
}
// 依次执行成功队列中的函数,直到队列中的函数执行完毕
const runFulfilled = (value) => {
let cb;
while ((cb = this._fulfilledQueues.shift())) {
cb(value);
}
};
// 依次执行失败队列的函数,直到队列中的函数执行完毕
const runReject = (error) => {
let cb;
while (cb == this._rejcetedQueues.shift()) {
cb(error);
}
};
// 成功时执行的函数
let fulfilled = (value) => {
try {
// 如果then方法传入的参数onFulfilled不是一个函数,直接执行promise的resolve方法
if (!isFunction(onFulfilled)) {
onFulfilledNext(value);
} else {
// 否则就执行onFulfilled回调函数
let res = onFulfilled(value);
// 如果onFulfilled回调函数的结果是一个Promise
if (res instanceof MyPromise) {
// 必须等待状态改变后,再去执行promise的resolve方法
res.then(onFulfilledNext, onRejectedNext);
} else {
// 如果onFulfilled回调函数的结果不是一个Promise,直接执行promise的resolve方法
onFulfilledNext(res);
}
}
} catch (error) {
// 如果函数执行出错,更新一下任务状态
onRejectedNext(error);
}
};
// 构造函数Promise必须接受一个函数作为参数,写一个方法,用户判断是否是函数
let isFunction = (fn) => {
return typeof fn === 'function';
};
// 定义三种状态
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
// myPromise 构造函数,接收一个函数作为参数
class MyPromise {
constructor(handle) {
if (!isFunction(handle)) {
throw new Error('MyPromise 必须传入一个函数');
}
// 初始化状态
this._status = PENDING;
// 初始化传递值
this._value = undefined;
// 添加成功回调函数队列
this._fulfilledQueues = [];
// 添加失败回调函数队列
this._rejcetedQueues = [];
try {
// 执行handle
handle(this._resolve.bind(this), this._reject.bind(this));
} catch (error) {
this._reject(error);
}
}
// 添加resolve时执行的函数
_resolve(val) {
// run方法
const run = () => {
// 如果状态不是PENDING状态,返回
if (this._status != PENDING) return;
// 依次执行成功队列中的函数,直到队列中的函数执行完毕
const runFulfilled = (value) => {
let cb;
while ((cb = this._fulfilledQueues.shift())) {
cb(value);
}
};
// 依次执行失败队列的函数,直到队列中的函数执行完毕
const runReject = (error) => {
let cb;
while (cb == this._rejcetedQueues.shift()) {
cb(error);
}
};
// 如果resolve中的参数是一个Promise对象,则必须等待这个Promise状态改变后,才去依次执行队列中的函数
// 当前Promise的状态才会改变,状态的改变取决于当前当前Promise的状态
if (val instanceof MyPromise) {
val.then(
(value) => {
this._value = value;
this._status = FULFILLED;
runFulfilled(value);
},
(err) => {
this._value = err;
this._status = REJECTED;
runReject(err);
}
);
} else {
// 如果resolve不是一个Promise对象,则依次执行成功队列中的函数
this._value = val;
this._status = FULFILLED;
runFulfilled(val);
}
};
// 异步执行run方法
setTimeout(run, 0);
}
// 添加reject时执行的函数
_reject(error) {
// 如果状态是PENDING,返回
if (this._status != PENDING) return;
// run方法
const run = () => {
this._status = REJECTED;
this._value = error;
let cb;
// 依次执行失败队列的中的函数,直到执行到最后一个
while ((cb = this._rejcetedQueues.shift())) {
cb(error);
}
};
// 异步执行run方法
setTimeout(run, 0);
}
// 添加then方法
then(onFulfilled, onRejected) {
// 获取到当前状态
const { _value, _status } = this;
// then方法返回一个Promise
return new MyPromise((onFulfilledNext, onRejectedNext) => {
// 成功时执行的函数
let fulfilled = (value) => {
try {
// 如果then方法传入的参数onFulfilled不是一个函数,直接执行promise的resolve方法
if (!isFunction(onFulfilled)) {
onFulfilledNext(value);
} else {
// 否则就执行onFulfilled回调函数
let res = onFulfilled(value);
// 如果onFulfilled回调函数的结果是一个Promise
if (res instanceof MyPromise) {
// 必须等待状态改变后,再去执行promise的resolve方法
res.then(onFulfilledNext, onRejectedNext);
} else {
// 如果onFulfilled回调函数的结果不是一个Promise,直接执行promise的resolve方法
onFulfilledNext(res);
}
}
} catch (error) {
// 如果函数执行出错,更新一下任务状态
onRejectedNext(error);
}
};
// 失败时执行的函数
let rejected = (error) => {
try {
// 如果then方法传入的参数onRejected不是一个函数,直接执行promise的resolve方法
if (!isFunction(onRejected)) {
onRejectedNext(error);
} else {
// 否则就执行onRejected函数
let res = onRejected(error);
// 如果onRejected函数的结果是一个Promise
if (res instanceof MyPromise) {
// 必须等待状态改变后,再去执行promise的resolve方法
res.then(onFulfilledNext, onRejectedNext);
} else {
// 如果onRejected函数的结果不是一个Promise,直接执行promise的resolve方法
onRejectedNext(error);
}
}
} catch (error) {
onRejectedNext(error);
}
};
switch (_status) {
// 当状态为PENDING,将then方法回调函数加入执行队列
case PENDING:
this._fulfilledQueues.push(fulfilled);
this._rejcetedQueues.push(rejected);
break;
// 如果是FULFILLED,执行成功时执行的回调函数
case FULFILLED:
fulfilled(_value);
break;
// 如果是REJECTED,执行失败时执行的回调函数
case REJECTED:
rejected(_value);
break;
}
});
}
// catch方法,catch方法实际上返回的是then,只不过只传入了Rejected状态的回调函数
catch(onRejected) {
return this.then(undefined, onRejected);
}
// 静态方法:resolve
static resolve(value) {
// 如果resolve传入的值是一个Promise,直接返回这个实例
if (value instanceof MyPromise) return value;
// 否则,就执行promise的resolve方法
return new MyPromise((resolve) => resolve(value));
}
// 静态方法:reject
static reject(value) {
// 执行promise的reject方法
return new MyPromise((resolve, reject) => reject(value));
}
// 静态方法:all
// all方法接收一个数组,数组的成员都是promise实例
// 返回一个promise实例,这个promise的状态取决于数组成员状态
// 只有成员都变成了fulfilled,当前promise的状态才会变成fullfilled
// 只要有一个成员的状态变成了rejected,当前promise的状态变成了rejected,第一个被rejected的成员的值传递给当前promise
static all(list) {
// console.log(list)
return new MyPromise((resolve, reject) => {
let values = [];
let count = 0;
for (let [i, p] of list.entries()) {
this.resolve(p).then(
(res) => {
values[i] = res;
count++;
if (count == list.length) resolve(values);
},
(err) => {
reject(err);
}
);
}
});
}
// 静态方法:race
// race方法接收一个数组,数组的成员都是promise实例
// 返回一个promise,promise 的状态取决于数组成员状态
// 只要有一个成员的状态变化了,那么当前promise的状态就会变化,第一个变化的返回值传递给当前promise
static race(list) {
return new MyPromise((reslove, reject) => {
for (let p of list) {
this.resolve(p).then(
(res) => {
reslove(res);
},
(err) => {
reject(err);
}
);
}
});
}
// finally:不管promise是什么状态,在执行完then或catch指定的回调函数,都会执行finally方法执行的回调函数
// 本质是then方法的特例
finally(cb) {
return this.then(
(value) => MyPromise.reslove(cb()).then(() => value),
(error) =>
MyPromise.resolve(cb()).then(() => {
throw error;
})
);
}
}
// then方法
var promise = new MyPromise((resolve, reject) => {
setTimeout(function() {
resolve('promise');
}, 1000);
});
promise.then(
(res) => {
console.log(res);
},
(error) => {
console.log(error);
}
);
// catch方法
var promise2 = new MyPromise((resolve, reject) => {
setTimeout(function() {
reject(new Error('ERROR'));
}, 1000);
});
promise2.catch((error) => {
console.log(error);
});
// 静态方法resolve
var promise3 = MyPromise.resolve('promise3');
promise3.then((res) => {
console.log(res);
});
// 静态方法reject
var promise4 = MyPromise.reject(new Error('ERROR'));
promise4.then(null, (error) => {
console.log(error);
});
// 静态方法all:有一个状态变成了rejected,promise状态就会变成reject,promise2状态是rejected
var promise5 = MyPromise.all([promise, promise2]);
promise5.then(
(res) => {
console.log(123123);
},
(err) => {
console.log(err);
}
);
// 静态方法all:所有状态变成fullfilled,promise状态就会变成fullfilled
var promise6 = MyPromise.all([promise, promise]);
promise6.then(
(res) => {
console.log(123123);
},
(err) => {
console.log(err);
}
);
// finally方法
var promise7 = new Promise((reslove, reject) => {
reslove('promise7');
});
promise7
.then(
(res) => {
console.log(res);
},
(error) => {}
)
.finally((value) => {
console.log('我是fanilly,但是我不知道当前promise状态');
});
// resolve中传入一个promise对象
var promise8 = new Promise((reslove, reject) => {
reslove(promise7);
});
promise8.then((res) => {
console.log('resolve中传入一个promise对象', res);
});
暂无评论
确认操作
请再次确认编辑图片
待上传图片 (剩余 0 张)
项目详情
确认评论邮箱
邀请制评论