用js实现promise
/*
自定义promise
1. 执行MyPromise构造函数,要立即执行executor
2. promise实例对象,内部有三种状态
初始化 pending
成功 resolved
失败 rejected
注意:状态只能修改一次
如果executor内部出错了,promise状态改成rejected
3. then方法的实现
promise.then(onResolved, onRejected)
promise的状态是resolved时,异步调用onResolved函数
promise的状态是rejected时,异步调用onRejected函数
promise的状态是pending时,不调用函数。
未来promise可能会变化,此时还是要异步调用相应的函数
4. promise.then().then()
then方法返回值是promise,才能链式调用
返回值promise对象的状态:
1. 如果内部没有返回值 / 返回值不是promise 就是resolved
2. 如果内部返回值是promise 看promise的状态
3. 如果内部抛异常,就是rejected
*/
function MyPromise(executor) {
// 初始化promise实例对象状态
this._status = 'pending';
// 初始化promise实例对象结果值
this._value = undefined;
// 初始化存储 回调函数 的容器
this._callbacks = {};
// 缓存this --> promise实例对象
const _that = this;
try {
// 放置可能出错代码
// 一旦try里面代码出错了,就会中断try中代码运行,直接来到catch
// 执行MyPromise构造函数,要立即执行executor
executor(resolve, reject);
} catch (e) {
// 来到catch,说明executor函数内部出错了~
// 将promise对象状态改成rejected
reject(e);
}
// 定义resolve
function resolve(value) {
// 状态只能修改一次
if (_that._status === 'pending') {
// 调用resolve方法将promise对象状态改成resolved状态
_that._status = 'resolved';
_that._value = value;
// 异步调用onResolved函数
if (_that._callbacks.onResolved) {
setTimeout(() => {
_that._callbacks.onResolved(value)
})
}
}
}
// 定义reject
function reject(reason) {
if (_that._status === 'pending') {
// 调用reject方法将promise对象状态改成rejected状态
_that._status = 'rejected';
_that._value = reason;
// 异步调用onRejected函数
if (_that._callbacks.onRejected) {
setTimeout(() => {
_that._callbacks.onRejected(reason)
})
}
}
}
}
MyPromise.prototype.then = function (onResolved, onRejected) {
const _that = this;
// 如果onResolved存在,不变
// 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise
onResolved = onResolved ? onResolved : (value) => value;
// then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值
onRejected = onRejected ? onRejected : (reason) => {
throw reason
};
// 为了将来作为promise对象使用
let promise = null;
// this指向promise实例对象
if (this._status === 'resolved') {
// 说明promise对象的状态是resolved
// 异步调用onResolved函数
promise = new MyPromise(function (resolve, reject) {
setTimeout(() => {
doResolve(onResolved, _that._value, resolve, reject);
})
})
} else if (this._status === 'rejected') {
promise = new MyPromise(function (resolve, reject) {
setTimeout(() => {
doResolve(onRejected, _that._value, resolve, reject);
})
})
} else {
// 说明promise对象的状态是pending状态
// 将回调函数存在this上
promise = new MyPromise(function (resolve, reject) {
// _that是p1, 外面promise是p2
// p1调用onResolved/onRejected回调时,要更新p2的状态
_that._callbacks.onResolved = function (value) {
doResolve(onResolved, value, resolve, reject);
};
_that._callbacks.onRejected = function (reason) {
doResolve(onRejected, reason, resolve, reject);
};
})
}
// 为了链式调用
return promise;
}
// 定义函数复用代码
function doResolve(onFn, value, resolve, reject) {
try {
const result = onFn(value);
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result);
}
} catch (e) {
reject(e);
}
}
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
}
MyPromise.prototype.finally = function (onResolved) {
const _that = this;
return new Promise((resolve, reject) => {
if (_that._status === 'pending') {
const callback = function (value) {
doResolve(onResolved, value, resolve, reject)
};
_that._callbacks.onResolved = callback;
_that._callbacks.onRejected = callback;
} else {
doResolve(onResolved, _that._value, resolve, reject);
}
})
}
// 返回一个成功状态promise
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
resolve(value);
})
}
// 返回一个失败状态promise
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
})
}
// 接受一个数组(数组中放置n个promise对象),只有所有promise对象都成成功状态,方法返回值的promise才是成功
// 只要有一个失败,方法返回值的promise就失败
MyPromise.all = function (promises) {
// promises的长度
const promiseLength = promises.length;
// 定义标识变量: promise对象成功的数量
let resolvedCount = 0;
// 成功的结果值
const resolvedValues = [];
return new MyPromise((resolve, reject) => {
for (let i = 0; i < promiseLength; i++) {
const promise = promises[i];
// 看promise的状态
promise.then((value) => {
resolvedCount++;
// 不能用push,输出顺序会乱
// 使用下标,才能保证顺序ok
resolvedValues[i] = value;
if (resolvedCount === promiseLength) {
// 说明都成功了
resolve(resolvedValues);
}
}, reject)
}
})
}
const promise = new MyPromise((resolve, reject) => {
console.log('executor函数执行了~');
setTimeout(() => {
// resolve(111);
reject(222);
}, 2000)
})
promise
.then(() => {
console.log(111);
// 当then方法没有传入第二个回调。
// 那么一旦接受的promise对象的状态是失败状态,返回值也是失败状态
})
.catch((reason) => {
console.log(222, reason);
// return Promise.reject();
// throw new Error(111)
return 333;
})
.then((value) => {
console.log(333, value);
})
.catch(() => {
console.log(444);
})