手写promise
根据promise A+规范
可以得出如下
需要注意的点:
1.为了防止调用then的时候,this指向的不是实例对象,所以需要用一个self保存this值.
2.关于定时器的使用,resolve和reject函数是需要加定时器的,这是因为.then是微任务,确保onFulfilled异步执行,且在 then 方法被调用的那一轮事件循环之后的新执行栈中执行。如果有异步函数,resolve在then后面执行.还有onFulfilled函数也需要加定时器,这个为了模仿微服务,加一个异步
手写promise总共分三个阶段
promise的状态
有三种:pending,fulfilled,rejected.pending表示待定,fulfilled表示成果,rejected,表示失败
then方法
.then是一个函数,有两个参数onFulfilled,onRejected
onFulfiled:状态为fulfilled的时候的回调函数,只能被执行一次,第一个参数是promise的value.
onRejected:状态为rejected的时候的回调函数,只能被执行一次,第一个参数是promise的reason.
then可以多次调用,用一个数组存储回调函数,状态变化时会按注册顺序调用
为了解决链式调用,.then会返回一个新promise
promise2 = promise1.then(onFulfilled, onRejected);
- 如果
onFulfilled或者onRejected返回一个值x,则运行下面的 Promise 解决过程:[[Resolve]](promise2, x) - 如果
onFulfilled或者onRejected抛出一个异常e,则promise2必须拒绝执行,并返回拒因e - 如果
onFulfilled不是函数且promise1成功执行,promise2必须成功执行并返回相同的值 - 如果
onRejected不是函数且promise1拒绝执行,promise2必须拒绝执行并返回相同的据因
解决函数
运行 [[Resolve]](promise, x) 需遵循以下步骤:
x 与 promise 相等
如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise
x 为 Promise
如果 x 为 Promise ,则使 promise 接受 x 的状态 注4:
- 如果
x处于等待态,promise需保持为等待态直至x被执行或拒绝 - 如果
x处于执行态,用相同的值执行promise - 如果
x处于拒绝态,用相同的据因拒绝promise
x 为对象或函数
如果 x 为对象或者函数:
-
把
x.then赋值给then注5 -
如果取
x.then的值时抛出错误e,则以e为据因拒绝promise -
如果
then是函数,将x作为函数的作用域this调用之。传递两个回调函数作为参数,第一个参数叫做resolvePromise,第二个参数叫做rejectPromise:-
如果
resolvePromise以值y为参数被调用,则运行[[Resolve]](promise, y) -
如果
rejectPromise以据因r为参数被调用,则以据因r拒绝promise -
如果
resolvePromise和rejectPromise均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用 -
如果调用
then方法抛出了异常e:- 如果
resolvePromise或rejectPromise已经被调用,则忽略之 - 否则以
e为据因拒绝promise
- 如果
-
如果
then不是函数,以x为参数执行promise
-
-
如果
x不为对象或者函数,以x为参数执行promise
function MyPromise(executor) {
this.state = 'pending';
this.onFulfilledCallback = [];
this.onRejectedCallback = [];
const self = this;
function resolve(value) {
setTimeout(function () {
if (self.state === 'pending') {
self.state = 'fulfilled';
self.data = value;
for (let i = 0; i < self.onFulfilledCallback.length; i++) {
self.onFulfilledCallback[i](value);
}
}
})
}
function reject(reason) {
setTimeout(function () {
if (self.state === 'pending') {
self.state = 'rejected';
self.data = reason;
for (let i = 0; i < self.onRejectedCallback.length; i++) {
self.onRejectedCallback[i](reason);
}
}
})
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function (onFulfilled, onRejected) {
const self = this;
let promise2;
return (promise2 = new MyPromise(function (resolve, reject) {
if (self.state === 'fulfilled') {
setTimeout(function () {
//如果onFulfilled是一个函数,运行,然后进行Promise解决过程,如果不是就忽略
if (typeof onFulfilled === 'function') {
try {
const x = onFulfilled(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
} else {
resolve(self.data);
}
});
} else if (self.state === 'rejected') {
setTimeout(function () {
if (typeof onRejected === 'function') {
try {
const x = onRejected(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
} else {
reject(self.data);
}
})
} else if (self.state === 'pending') {
self.onFulfilledCallback.push(function (promise1Value) {
if (typeof onFulfilled === 'function') {
try {
const x = onFulfilled(self.data)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error);
}
} else {
resolve(promise1Value);
}
});
self.onRejectedCallback.push(function (promise1Reason) {
if (typeof onRejected === 'function') {
try {
const x = onRejected(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
} else {
reject(promise1Reason);
}
});
}
}));
};
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('循环利用'));
}
if (x instanceof MyPromise) {
if (x.state === 'pending') {
//等待它转变,所以执行和上面一样的操作
x.then(function (value) {
resolvePromise(promise2, value, resolve, reject)
}, reject);
} else if (x.state === 'fulfilled') {
//如果这个promise是fulfilled,那么promise2就直接解决了
resolve(x.data);
} else if (x.state === 'rejected') {
reject(x.data);
}
return;
}
if (x && (typeof x === "object" || typeof x === "function")) {
let isCalled = false;
try {
let then = x.then;
if (typeof then === "function") {
then.call(x,
function rs(y) {
if (isCalled) return;
isCalled = true;
return resolvePromise(promise2, y, resolve, reject);
},
function rj(e) {
if (isCalled) return;
isCalled = true;
return reject(e);
}
);
} else {
resolve(x);
}
} catch (error) {
if (isCalled) return;
isCalled = true;
reject(error);
}
} else {
resolve(x);
}
}
静态方法
Promise.all,race,allsettled,resolve,reject
//如果传入的参数时promise那就直接返回,如果不是就返回一个状态为fulfilled的promise
Promise.resolve=(value)=>{
if(value instanceof Promise){
return value
}
else{
return new Promise((resolve, reject) => {
resolve(value)
})
}
}
//直接返回一个状态为reject的promise
Promise.reject=(reason)=>{
return new Promise((resolve, reject) => {
reject(reason)
})
}
//返回一个promise,如果所有都成功才是fulfilled,返回一个带所有promise的数组,有一个reject那就reject
Promise.all=(promises)=>{
let count =0;//定义计数器,用来知道有几个返回成功
let len = promises.length;
let result = [];//所有 promise 的 resolve之后返回的结果
return new Promise((resolve,reject)=>{
promises.forEach((params,index)=>{
Promise.resolve(params).then((value)=>{
count++;
result[index]=value;
if(count== len){
resolve(result)
}
},(reason)=>{
reject(reason)
})
})
})
}
//只要有一个改变状态就返回,所以对每一个promise.promise.then(resolve,reject).只要有一个参数改变就返回
Promise.rece=(promises)=>{
return new Promise((resolve, reject) => {
promises.forEach((p)=>{
Promise.resolve(p).then(resolve).catch(reject)
})
})
}
//所有promise都改变状态才返回,返回一个数组,状态永远是fulfilled.
Promise.allSettled=(promises)=>{
let count =0;
let result=[];
let len = promises.length;
return new Promise((resolve, reject) => {
promises.forEach((p,i)=>{
Promise.resolve(p).then((value)=>{
count++;
result[i]={
state:'fulfilled',
value:value
};
if(count == len){
resolve(result)
}
},(reason)=>{
count++;
result[i]={
state:'rejected',
reason:reason
};
if(count == len){
resolve(result)
}
}
)
})
})
}