基础版promise
1.先实现一个简易版的promise,符合下面几个规范稍后在完善
- promise必须是一个function 或者 object,必须有一个then方法。
- promise有三种状态 :请求态(pending), 完成态(fulfilled),拒绝态(rejected),初始状态是请求态pending,只能从pending -> fulfilled (对应一个成功的原因value)或者pending -> rejected (对应一个失败的原因 reason,且状态改变之后就不能更改。
- promise接受一个executor构造器 同步执行,构造器需要抛出异常,executor接受两个参数 resolve 和 reject, then方法接受两个参数onFulfilled 和 onRejected。
- onFulfilled 必须在调用resolve之后执行,onRejected 必须在调用reject之后执行, 如果excutor里面没有调用resolve或者reject的时候 promise仍然处于pending态,那么then方法的回调是不会执行的, 如果executor 里面异步调用(mutationobserver, setImmediate setTimeout调用 例子采用settimeout)了resolve或者reject 这个时候promise仍然处于pending态, 需要用发布订阅模式将then的函数回调保存下来,在下一个事件队列的宏任务中执行resolve或者reject的时候 发布之前保存下来的结果,然后依次执行。
const PENDING = Symbol('pending');
const FULFILLED = Symbol('fulfilled');
const REJECTED = Symbol('rejected');
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallBackList = [];
this.onRejectedCallBackList = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onFulfilledCallBackList.forEach((callBack) => callBack());
}
};
const rejected = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallBackList.forEach((callBack) => callBack());
}
};
try {
executor(resolve, rejected);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
if (this.status === FULFILLED) {
onFulfilled(this.value);
}
if (this.status === REJECTED) {
onRejected(this.reason);
}
if (this.status === PENDING) {
this.onFulfilledCallBackList.push(() => {
onFulfilled(this.value);
});
this.onRejectedCallBackList.push(() => {
onRejected(this.reason);
});
}
}
}
2.链式调用的promise
then(onFulfilled, onRejected) {
let promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
try {
let x = onFulfilled(this.value);
resolve(x);
} catch (error) {
reject(error);
}
}
if (this.status === REJECTED) {
try {
let x = onRejected(this.reason);
resolve(x);
} catch (error) {
reject(error);
}
}
if (this.status === PENDING) {
this.onFulfilledCallBackList.push(() => {
try {
let x = onFulfilled(this.value);
resolve(x);
} catch (error) {
reject(error);
}
});
this.onRejectedCallBackList.push(() => {
try {
let x = onRejected(this.reason);
resolve(x);
} catch (error) {
reject(error);
}
});
}
});
return promise2;
}
3 完整版的promise
// 1) Promise 是一个类或者一个方法
// 2) Promise 有三种状态 pending (等待态) fulfilled (成功态) rejected (失败态)
// 默认为pending态
// 只有是pending态的时候才能更改状态为fulfilled 或者 rejected 状态一旦更改就不允许再次被修改
// 3) Promise 内部提供一个成功的value, 一个失败的reason
// 4) Promise 内部提供两个方法 一个resolve 一个reject
// 如果两个方法都不传 默认返回undefined
// resolve或者reject不能抛异常 代码会直接报错
// resolve接收成功的value reject接收失败的reason
// 调用resolve 会把状态从 pending 更改为 fulfilled
// 调用reject 会把状态从 pending 更改为 rejected
// 如果在executor 执行器中异步调用resolve或者reject 例如setTimeout调用
// 如果在异步任务重抛出异常 则会直接执行这个throw抛出的 不会走入到下面的then方法的回调了
// then回调时候状态依然是pending态 需要发布订阅模式处理 将订阅的存放在数组里面
// 为什么存放的是一个数组呢 应为一个实例 可以then多次 一个多次订阅
// 成功的onFulfilledCallBacks 失败的onRejectedCallBacks
// 5) Promise 接收一个 executor 执行器, 默认会立即执行
// 第一个参数就是内部提供的resolve 第二个参数就是内部提供的参数reject
// 多个resolve跟reject嵌套的话 应该以最后一个的作为结果
// 6) Promise 有个then函数 默认有两个参数onFulfilled 和 onRejected
// onFulfilled resolve或者reject调用之后返回的是一个普通值或者一个新的promise调用的resolve的值
// 将value作为参数传递给onFulfilled
//
// onRejected resolve和reject调用之后的回调返回一个promise的reject的值或者抛出异常 将reason作为参数传递给onRejected
// then有返回值
// catch的特点是 如果都没有错误处理 一层层找 没有找到错误处理 会找最近的catch catch也是then
// promise中实现链式调用 返回一个新的promise
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
// 判断x的状态 是让promise2 变成 成功态 还是失败
// 此方法为了兼容所有的promise库 尽可能详细 不出错
function resolvePromise(promise2, x, resolve, reject) {
/** PromiseA+ 2.3.2 不能引用同一个对象 会造成死循环*/
if (promise2 === x) {
return reject(
new TypeError('Chaining cycle detected for promise #<Promise>')
);
}
if ((typeof x === 'object' && x != null) || typeof x === 'function') {
// x如果是对象或者函数 说明他有可能是个对象
/** PromiseA+ 2.3.2.2
* 取之可能会报错 then方法可能是由getter定义的
* Object.defineProperty(promise, 'then', {
* get () {
* throw new Error();
* }
* })
* */
let called;
try {
let then = x.then;
if (typeof then === 'function') {
/** PromiseA+ 2.3.2.2
* let obj = {
* index: 0,
* get then () {
* if (++this.index=== 2) throw error
* }
* }
* obj.then 就会执行
*/
// 相当于传进来的值是reject
then.call(
x,
(y) => {
// PromiseA+ 2.3.3.3
// 防止一个promise调用多次 走完成功再走失败 或者走完失败 再走成功 或者一直走成功 或者一直走失败
if (called) return;
called = true;
// 防止resolve 返回的还是promise 递归解析 直到是一个普通值为止
resolvePromise(promise2, y, resolve, reject);
},
(r) => {
// PromiseA+ 2.3.3.3
if (called) return;
called = true;
reject(r);
}
);
} else {
resolve(x);
}
} catch (e) {
// PromiseA+ 2.3.3.3
if (called) return;
called = true;
reject(e);
}
} else {
//这里有问题写的
// 普通值 直接成功就好了
resolve(x);
}
}
function isPromise(x) {
if ((typeof x === 'object' && x != null) || typeof x === 'function') {
try {
let x = x.then;
if (typeof x.then === 'function') {
return true;
}
return false;
} catch (error) {
return false;
}
}
return false;
}
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallBacks = [];
this.onRejectedCallBacks = [];
let resolve = (value) => {
if (value instanceof Promise) {
return value.then(resolve, reject);
}
if (this.status === PENDING) {
//PromiseA+ 2.1.1
this.status = FULFILLED;
this.value = value;
this.onFulfilledCallBacks.forEach((fn) => fn());
}
};
let reject = (reason) => {
if (this.status === PENDING) {
//PromiseA+ 2.1.1
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallBacks.forEach((fn) => fn());
}
};
try {
//PromiseA+ 1.1.4
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
//PromiseA+ 2.1.1
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (v) => v;
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err;
};
// PromiseA+ 2.2.7
// 为了实现链式调用 创建一个新的promise
let promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
// 执行then中的方法 可能返回的是一个普通值 或者promise执行
// 我要判断x的类型是不是一个promise 如果是promise的话 我要让这个promise执行
// 并采用他的状态 作为promise的成功或者失败
/** PromiseA+ 2.2.4*/
setTimeout(() => {
/** PromiseA+ 2.2.7.2*/
try {
// 一旦执行then方法报错 就走到外层then的错误处理中 调用promise2的reject方法中
let x = onFulfilled(this.value);
/** PromiseA+ 2.2.7.1*/
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
/** PromiseA+ 2.2.4*/
setTimeout(() => {
/** PromiseA+ 2.2.7.2*/
try {
let x = onRejected(this.reason);
/** PromiseA+ 2.2.7.1*/
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === PENDING) {
this.onFulfilledCallBacks.push(() => {
// 切片编程
/** PromiseA+ 2.2.4*/
setTimeout(() => {
/** PromiseA+ 2.2.7.2*/
try {
// 一旦执行then方法报错 就走到外层then的错误处理中 调用promise2的reject方法中
let x = onFulfilled(this.value);
/** PromiseA+ 2.2.7.1*/
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallBacks.push(() => {
/** PromiseA+ 2.2.4*/
setTimeout(() => {
/** PromiseA+ 2.2.7.2*/
try {
// 一旦执行then方法报错 就走到外层then的错误处理中 调用promise2的reject方法中
let x = onRejected(this.reason);
/** PromiseA+ 2.2.7.1*/
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
// 切片编程
});
}
});
return promise2;
}
catch(errCallBack) {
return new Promise((resolve, reject) => {
resolve(this.then(null, errCallBack));
});
}
finally(callback) {
return this.then(
(value) => new Promise.resolve(callback()).then(() => value),
(reason) =>
new Promise.resolve(callback()).then(() => {
throw reason;
})
);
}
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
let result = promises[i];
if(isPromise(result)){
result.then(resolve,reject)
}else{
resolve(result);
}
}
});
}
static all(promises) {
return new Promise((resolve, reject) => {
let result = [];
let times = 0;
function processData(index, val) {
result[index] = val;
if (++times === promises.length) {
resolve(result);
}
}
for (let i = 0; i < promises.length; i++) {
let p = promises[i];
if (isPromise(p)) {
p.then((data) => {
processData(i, data); // 普通值
}, reject);
} else {
processData(i, p); // 普通值
}
}
});
}
static resolve(params) {
return new Promise((resolve, reject) => {
resolve(params);
});
};
static reject(params) {
return new Promise((resolve, reject) => {
reject(params);
});
};
}
// npm install -g promises-aplus-tests
// promises-aplus-tests 文件名
Promise.defer = Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};
module.exports = Promise;