最近我看了很多与promise相关的文章以及书籍,我觉得他们并没有将promise讲的特别透彻,比如promise的resolve是一个带有then方法的对象会是怎么样,尤其这一点特别重要在讲实现async await的时候这一点尤其的重要,接下来请大家忘记自己之前学的东西,和我一起梳理一下promise
promise的含义
promise一个采用订阅发布设计模式进行设计的容器,准确的说只有外界通过函数进行订阅了以后,里面会发布出某个将来才会得到的结果(通常是一个异步操作)的结果。
promise的特点
状态不受外界影响
Promise对象代表一个异步操作,有三种状态
- pending(进行中)
- fulfilled(已成功)
- rejected(已拒绝)
只有reject,resolve可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
const p = new Promise((resolve, reject) =>{});
p.then(() => {
console.log('pending');
});
console.log(p, 'pending');
上述代码由于promise内部没有调用resolve或者reject,所以promise的状态还是pending状态 下面我们将通过调用resolve来进行改变promise的状态
const p = new Promise((resolve, reject) =>{
resolve();
});
p.then(() => {
console.log('fulfilled');
});
console.log(p, 'fulfilled');
下面我们将通过调用reject来进行改变promise的状态
const p = new Promise((resolve, reject) =>{
reject();
});
p.then(() => {
console.log('fulfilled');
}).catch(() => {
console.log('rejected')
});
console.log(p, 'rejected');
一旦状态改变,就不会再变
Promise对象的状态改变,只有两种可能:
- pending -> fulfilled
- pending -> rejected
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果
const p = new Promise((resolve, reject) =>{
resovle();
reject();
});
p.then(() => {
console.log('fulfilled');
}).catch(() => {
console.log('rejected')
});
console.log(p, 'fulfilled');
const p = new Promise((resolve, reject) =>{
reject();
resolve();
});
p.then(() => {
console.log('fulfilled');
}).catch(() => {
console.log('rejected')
});
console.log(p, 'rejected');
promise的基本用法
promise是构造函数
Promise对象是一个构造函数,用来生成Promise实例。
const a = new Promie();
promise接受一个函数
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,都是函数
reslove函数传参
如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数。resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = new Promise((resolve, reject) =>{
resolve(p);
});
p.then((name) => {
console.log(name); // zgl
});
p1.then((name) => {
console.log(name); // zgl
});
这时p的状态就会传递给p1,也就是说,p的状态决定了p1的状态。如果p的状态是pending,那么p1的回调函数就会等待p的状态改变;如果p的状态已经是resolved或者rejected那么p1的回调函数将会立刻执行
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = new Promise((resolve, reject) =>{
resolve(p);
});
p1.then((name) => {
console.log(name); // zgl
});
const p2 = new Promise((resolve, reject) =>{
reject(new Error('reject'));
});
const p3 = new Promise((resolve, reject) =>{
resolve(p2); // 未执行p2
});
p3.then((name)=>{
console.log(name)
},(error) => {
console.log(error);
/* error: reject
at <anonymous>:2:10
at new Promise (<anonymous>)
at <anonymous>:1:12
*/
});
reject函数传参
reject函数的参数通常是Error对象的实例,表示抛出的错误
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then((name) => {
console.log(name);
},(error)=> {
console.log(error); // zgl
});
promise对象常见的方法
then方法
then参数支持传入2个函数
Promise实例生成以后,可以在then方法传入2个函数参数分别监听resolved状态和rejected状态的回调函数,
const p = new Promise((resolve, reject) =>{
resolve();
});
p.then(() => {
console.log('fulfilled');
});
const p1 = new Promise((resolve, reject) =>{
reject();
});
p1.then(()=>{},() => {
console.log('fulfilled');
});
const p = new Promise((resolve, reject) =>{
reject();
});
p.then(()=>{},() => {
console.log('rejected')
});
第一个函数接受resolve函数的参数
如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给then的第一个参数。resolve函数的参数除了正常的值以外,还可能是带有then方法的对象,只有当前对象resolveed或者rejected才会改变当前promise的状态
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
p.then((name) => {
console.log(name); // zgl
});
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = new Promise((resolve, reject) =>{
resolve(p);
});
p1.then((name) => {
console.log(name); // zgl
});
这时如果传入的参数为带有then的方法的对象那么就会执行该对象的then方法
const obj = {
age: '24',
then() {
console.log(this.age); // 24
}
};
const p1 = new Promise((resolve, reject) =>{
resolve(obj);
});
p1.then(() => {
});
第二个函数接受reject函数的参数
reject函数的参数通常是Error对象的实例,表示抛出的错误
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then((name) => {
console.log(name);
},(error)=> {
console.log(error); // zgl
});
then返回新的promise
then方法的返回值是一个新的promise
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = p.then((name) => {
console.log(name); // zgl
});
console.log(p1 instanceof Promise) // true;
console.log(p1 === p) // false
then方法支持链式调用
then方法返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = p.then((name) => {
console.log(name); // zgl
}).then(()=> {
console.log(2222);
});
第一个then的返回值会传入第二个then函数的形参中
第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数,第一个then函数的返回值除了正常的值以外,还可能是带有then方法的对象,只有当前对象resolved或者rejected才会将resolved的值传入第二个then的形参中
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = p.then((name) => {
return name;
}).then((name)=> {
console.log(name); // zgl
});
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = new Promise((resolve, reject) =>{
resolve(24);
});
p.then((name) => {
return p1 ;
}).then((age)=> {
console.log(age); // 24
});
如果then的返回值为一个带有then的对象,那么就会调用该对象的then方法。
const obj = {
age: '24',
then() {
console.log(this.age); // 24
}
};
const p1 = new Promise((resolve, reject) =>{
resolve('zgl');
});
p1.then(() => {
return obj
}).then((obj) => {
console.log(obj)
})
then方法第一个参数传入不是函数时,会一直传递
当传入then的第一个参数不为函数时,此时promise resolved的值会一直传递下去,直到某个then的第一个参数为函数时
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
const p1 = p.then().then().then((name)=> {
console.log(name); // zgl
});
当promise发生错误时,then的第二个参数不为函数时,此时promise rejected的值会一直传递下去,直到某个then的第二个参数捕获到当前错误
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
const p1 = p.then(()=> {}).then(()=>{}).then(()=>{},(name)=> {
console.log(name); // zgl
});
then方法可以监听多个回调函数
对于同一个promise的then方法是能够注册多个回调函数的
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
p.then((name)=> {
console.log(name);
});
p.then((name)=> {
console.log(name);
});
catch方法
catch方法是then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
catch是then(undefined, rejection)的语法糖
catch是为了方便then能够更加方便的,简化捕获错误的过程,then能够支持的。catch都能够支持
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined, (name)=> {
console.log(name); // zgl
});
p.catch(name => {
console.log(name); //zgl
})
我们再来看看下面的几段代码思考一下
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined, (name)=> {
console.log(name); // zgl
});
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined, (name)=> {
return new Promise((resolve, reject) =>{
reject(27);
})
}).then(undefined, (age) => {
console.log(age); // 27
})
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined, (name)=> {
return new Promise((resolve, reject) =>{
reject(27);
})
})
}).then(undefined, (age) => {
return new Promise((resolve, reject) =>{
reject('xxxx');
}).then(undefined, (val) => {
console.log(val); // xxxx
})
通过以上实验发现,then的第二个参数作为函数时只能捕获前面一个promise产生的错误,并不能捕获到一开始就状态为rejected的promise,还记得在then中如果第二个参数不为函数时会直到为某个函数时才会捕获
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined).then(undefined, (age) => {
console.log(age)
})
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
p.then(() => {
return new Promise((resolve, reject) =>{
reject(27);
});
}).then(undefined, (age) => {
console.log(age)
})
我们只要在最后一个then的函数中进行捕获错误,就不需要考虑前面是否有捕获错误,但是这个写法还是很乏锁因此我们再一次简化,就有了catch方法
const p = new Promise((resolve, reject) =>{
resolve('zgl');
});
p.then(() => {
return new Promise((resolve, reject) =>{
reject(27);
});
}).catch((age) => {
console.log(age)
})
有then捕获异常后不会传递到catch中
const p = new Promise((resolve, reject) =>{
reject('zgl');
});
p.then(undefined, (age) => {
console.log(age)
}).catch((age) => {
console.log(age, 'age') // 不会执行
})
因此建议在实际使用过程中因在最后一个then进行追加catch这样就不需要在then中写每一个异常处理的逻辑,因此,建议总是使用catch()方法,而不使用then()方法的第二个参数。
promise对象的实现原理
promise是构造函数
由于浏览器实现的promie是一个函数,因此我们也需要遵循promise是一个构造函数
class MyPromise {
constrouctor(){}
}
promise对象接受一个函数
通过在promise的基本用法中分析,promise构造函数必须接受一个函数
function isFunction(val) {
return typeof val === 'function';
}
class MyPromise {
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`)
}
}
}
执行器函数接受2个参数
executor函数必须接受2个参数,第一个参数resolve必须是一个函数,第二个参数是选传
function isFunction(val) {
return typeof val === 'function';
};
class MyPromise {
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`)
}
executor(this.resolve, this.reject);
}
resolve() {};
reject(){};
}
resolve绑定的this为promise对象
const p = new Promise(function (resolve) {
resolve()
})
上述代码按照正常逻辑来讲的话,resolve的this指向了window,但是我们在执行的时候并没有报错说明了this并不是指向window而是指向了promise实例
function isFunction(val) {
return typeof val === 'function';
};
class MyPromise {
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
executor(this.resolve, this.reject);
}
resolve() {};
reject(){};
}
resolve函数将状态由pending -> fulfilled
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve() {
if (this.status === PENDING) {
this.status = FULFILLED;
}
}
reject(){}
}
resolve函数将状态由pending -> rejected
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise
status;
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve() {
if (this.status === PENDING) {
this.status = FULFILLED;
}
}
reject(){
if (this.status === PENDING) {
this.status = REJECTED;
}
};
}
resolve函数支持传参
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result
}
}
reject(){
if (this.status === PENDING) {
this.status = rejected;
}
}
}
reject函数支持传参
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise
status;
result;
error;
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
}
};
reject会捕获resolve的错误
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
error;
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
}
};
then方法
then参数的第一个值为resolved的值
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
error;
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
}
then((resolved) => {
resolved(this.result)
})
}
};
then参数的第二个值为resolved的值
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
error;
constructor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
}
then((resolved,reject) => {
try {
resolved(this.result)
}catch(e) {
reject(this.error)
}
})
}
};
then方法是异步的
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
error;
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
}
then((resolved,reject) => {
queueMicrotask(() => {
try {
resolved(this.result)
}catch(e) {
reject(this.#error)
}
})
})
}
};
then方法能够进行多次监听
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
result;
error;
resolevedQueue = [];
rejectedQueue = [];
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
this.status = FULFILLED;
this.result = result;
while(resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result)
}
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
while(rejectedQueue.length) {
const rejected = this.rejectQueue.shift();
rejected(error)
}
}
then((resolved,reject) => {
this.resolvedQueue.push(resolved);
this.rejectedQueue.push(reject);
})
}
};
只有状态为pending时才会进行注册
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolevedQueue = [];
rejectedQueue = [];
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
while(resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result)
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
while(rejectedQueue.length) {
const rejected = this.rejectedQueue.shift();
rejected(error);
}
}
then((resolved,reject) => {
switch(this.status) {
case PENDING:
this.resolvedQueue.push(resolved);
this.rejectedQueue.push(reject);
break;
case FULFILLED: resolved(this.result);
break;
case REJECTED: reject(this.error);
break;
default: throw new
}
})
}
};
then返回一个新的promise
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolevedQueue = [];
rejectedQueue = [];
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
while(resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result)
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
while(rejectedQueue.length) {
const rejected = this.rejectedQueue.shift();
rejected(error);
}
then((resolved,reject) => {
return new MyPromise((resolve, reject) => {
switch(this.status) {
case PENDING:
this.resolvedQueue.push(resolved);
this.rejectedQueue.push(reject);
break;
case FULFILLED: resolve(this.result);
break;
case REJECTED: reject(this.error);
break;
default: throw new Error('状态没有改变');
}
})
})
}
};
then的第一个参数的执行结果会传入返回的promise中
function isFunction(val) {
return typeof val === 'function';
};
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolevedQueue = [];
rejectedQueue = [];
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.status === PENDING
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
while(resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result)
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
while(rejectedQueue.length) {
const rejected = this.rejectedQueue.shift();
rejected(error);
}
then((resolved,rejected) => {
return new MyPromise((resolve, reject) => {
try {
switch(this.status) {
case PENDING:
this.resolvedQueue.push(resolved);
this.rejectedQueue.push(reject);
break;
case FULFILLED:
const result = resolved(this.result);
resolve(result);
break;
case REJECTED:
rejected(this.error);
break;
default: throw new Error('状态没有改变');
}
}catch(e) {
reject(e);
}
})
})
}
};
promise的第一个参数的执行结果为带有then的对象时会执行then方法
function isFunction(val) {
return typeof val === 'function';
};
function isObject(val) {
return typeof val === 'object' && val !== null;
}
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolevedQueue = [];
rejectedQueue = [];
constrouctor(executor){
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
executor(this.resolve, this.reject);
}
resolve(result) {
try {
if (this.status === PENDING) {
while(resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result)
}
this.status = FULFILLED;
});
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
while(rejectedQueue.length) {
const rejected = this.rejectedQueue.shift();
rejected(error);
}
then((resolved,rejected) => {
return new MyPromise((resolve, reject) => {
try {
const resolvePromise = (result, resolve, reject)=> {
try {
if (isFunction(result) || isObject(result)) {
if (isFunction(result.then)) {
result.then((result) => {
// 确保返回的promise已经初始化完成
queueMicrotask(() => {
resolvePromise(result, resolve, reject);
})
}, (error) => {
reject(error);
})
} else {
resolve(result);
}
} else {
resolve(result)
}
}catch(e) {
reject(e);
}
}
switch(this.status) {
case PENDING:
this.resolvedQueue.push(resolved);
this.rejectedQueue.push(reject);
break;
case FULFILLED:
queueMicrotask(() => {
const result = resolved(this.result);
resolvePromise(result, resolve, reject);
})
break;
case REJECTED:
rejected(this.#error);
break;
default: throw new Error('状态没有改变');
}
}catch(e) {
reject(e);
}
})
})
}
};
then的第一个参数不为函数时会传递结果
function isFunction(val) {
return typeof val === 'function';
};
function isObject(val) {
return typeof val === 'object' && val !== null;
}
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolveQueue;
rejectQueue;
constructor(executor) {
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
}
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.resolveQueue = [];
this.rejectQueue = [];
this.status = PENDING;
executor(this.resolve, this.reject);
};
resolve(result) {
if (isObject(result) && isFunction(result.then)){
result.then(this.resolve, this.reject);
return;
}
try {
if (this.status === PENDING) {
this.result = result;
while(this.resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result);
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (isObject(error) && isFunction(error.then)){
error.then(this.resolve, this.reject);
return;
}
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
while(this.rejectQueue.length) {
const rejected = this.rejectQueue.shift();
rejected(error);
}
}
}
then(resolved,rejected) {
if (!isFunction(resolved)) {
resolved = function resolve(result) {
return result;
}
}
if (!isFunction(rejected)) {
rejected = function reject(error) {
throw error ;
}
}
return new MyPromise((resolve, reject) => {
try {
let called = false;
const resolvePromise = (result, resolve, reject)=> {
try {
if (isFunction(result) || isObject(result)) {
if (isFunction(result.then)) {
result.then((result) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
// 确保返回的promise已经初始化完成
queueMicrotask(() => {
resolvePromise(result, resolve, reject);
})
}, (error) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
reject(error);
})
} else {
resolve(result);
}
} else {
resolve(result)
}
}catch(e) {
reject(e);
}
}
switch(this.status) {
case PENDING:
this.resolveQueue.push((result) => {
queueMicrotask(() => {
const res = resolved(result);
resolvePromise(res, resolve, reject);
})
});
this.rejectQueue.push((result) => {
queueMicrotask(() => {
const res = reject(result);
resolvePromise(res, resolve, reject);
})
});
break;
case FULFILLED:
queueMicrotask(() => {
const result = resolved(this.result);
resolvePromise(result, resolve, reject);
})
break;
case REJECTED:
rejected(this.error);
break;
default: throw new Error('状态没有改变');
}
}catch(e) {
rejected(e);
}
})
}
static resolve(value) {
if (value instanceof MyPromise) {
return value
}
return new MyPromise((resolve, reject) => {
try {
resolve(value);
}catch(e) {
reject(e);
}
})
}
};
then返回的是一个对象,then方法有且仅会执行一次
function isFunction(val) {
return typeof val === 'function';
};
function isObject(val) {
return typeof val === 'object' && val !== null;
}
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolveQueue;
rejectQueue;
constructor(executor) {
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
}
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.resolveQueue = [];
this.rejectQueue = [];
this.status = PENDING;
executor(this.resolve, this.reject);
};
resolve(result) {
try {
if (this.status === PENDING) {
this.result = result;
while(this.resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result);
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
while(this.rejectQueue.length) {
const rejected = this.rejectQueue.shift();
rejected(error);
}
}
}
then(resolved,rejected) {
if (!isFunction(resolved)) {
resolved = function resolve(result) {
return result;
}
}
if (!isFunction(rejected)) {
rejected = function reject(error) {
throw error ;
}
}
return new MyPromise((resolve, reject) => {
try {
let called = false;
const resolvePromise = (result, resolve, reject)=> {
try {
if (isFunction(result) || isObject(result)) {
if (isFunction(result.then)) {
result.then((result) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
// 确保返回的promise已经初始化完成
queueMicrotask(() => {
resolvePromise(result, resolve, reject);
})
}, (error) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
reject(error);
})
} else {
resolve(result);
}
} else {
resolve(result)
}
}catch(e) {
reject(e);
}
}
switch(this.status) {
case PENDING:
this.resolveQueue.push((result) => {
queueMicrotask(() => {
const res = resolved(result);
resolvePromise(res, resolve, reject);
})
});
this.rejectQueue.push((result) => {
queueMicrotask(() => {
const res = reject(result);
resolvePromise(res, resolve, reject);
})
});
break;
case FULFILLED:
queueMicrotask(() => {
const result = resolved(this.result);
resolvePromise(result, resolve, reject);
})
break;
case REJECTED:
rejected(this.error);
break;
default: throw new Error('状态没有改变');
}
}catch(e) {
rejected(e);
}
})
}
static resolve(value) {
if (value instanceof MyPromise) {
return value
}
return new MyPromise((resolve, reject) => {
try {
resolve(value);
}catch(e) {
reject(e);
}
})
}
};
MyPromise.resolve().then(() => {
console.log(0); // 一个微任务
return MyPromise.resolve(4); // 2个微任务 [微任务0, 微任务1, 微任务01, 微任务11, 微任务111, 微任务12]
}).then((res) => {
console.log(res)
})
MyPromise.resolve().then(() => {
console.log(1); // 一个微任务
}).then(() => {
console.log(2); // 一个微任务
}).then(() => {
console.log(3); // 一个微任务
}).then(() => {
console.log(5); // 一个微任务
}).then(() =>{
console.log(6); // 一个微任务
});
// 0 1 2 3 4 5 6
// 0 1 4 2 3 5 6
传入resolve的为一个带有then的对象时会执行
function isFunction(val) {
return typeof val === 'function';
};
function isObject(val) {
return typeof val === 'object' && val !== null;
}
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status;
resolveQueue;
rejectQueue;
constructor(executor) {
if (!isFunction(executor)) {
throw new TypeError(`MyPromise resolver ${typeof executor} is not a function
at new MyPromise`);
}
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.resolveQueue = [];
this.rejectQueue = [];
this.status = PENDING;
executor(this.resolve, this.reject);
};
resolve(result) {
if (isObject(result) && isFunction(result.then)){
result.then(this.resolve, this.reject);
return;
}
try {
if (this.status === PENDING) {
this.result = result;
while(this.resolveQueue.length) {
const resolved = this.resolveQueue.shift();
resolved(result);
}
this.status = FULFILLED;
}
}catch(e) {
this.reject(e);
}
}
reject(error) {
if (isObject(error) && isFunction(error.then)){
error.then(this.resolve, this.reject);
return;
}
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
while(this.rejectQueue.length) {
const rejected = this.rejectQueue.shift();
rejected(error);
}
}
}
then(resolved,rejected) {
if (!isFunction(resolved)) {
resolved = function resolve(result) {
return result;
}
}
if (!isFunction(rejected)) {
rejected = function reject(error) {
throw error ;
}
}
return new MyPromise((resolve, reject) => {
try {
let called = false;
const resolvePromise = (result, resolve, reject)=> {
try {
if (isFunction(result) || isObject(result)) {
if (isFunction(result.then)) {
result.then((result) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
// 确保返回的promise已经初始化完成
queueMicrotask(() => {
resolvePromise(result, resolve, reject);
})
}, (error) => {
if (called) {
return;
}; // 确保只执行一次
called = true;
reject(error);
})
} else {
resolve(result);
}
} else {
resolve(result)
}
}catch(e) {
reject(e);
}
}
switch(this.status) {
case PENDING:
this.resolveQueue.push((result) => {
queueMicrotask(() => {
const res = resolved(result);
resolvePromise(res, resolve, reject);
})
});
this.rejectQueue.push((result) => {
queueMicrotask(() => {
const res = reject(result);
resolvePromise(res, resolve, reject);
})
});
break;
case FULFILLED:
queueMicrotask(() => {
const result = resolved(this.result);
resolvePromise(result, resolve, reject);
})
break;
case REJECTED:
rejected(this.error);
break;
default: throw new Error('状态没有改变');
}
}catch(e) {
rejected(e);
}
})
}
static resolve(value) {
if (value instanceof MyPromise) {
return value
}
return new MyPromise((resolve, reject) => {
try {
resolve(value);
}catch(e) {
reject(e);
}
})
}
};