什么是 Promise
参考 MDN 定义Promise
cosnt p = new Promise((resolve,reject)=>{})
一个 Promise 必然处于以下几种状态之一:
peding:初始状态,既没有被兑现,也没有被拒绝。
fulfilled:意味着操作成功完成。
rejected:意味着操作失败。
为什么使用Promise
假设有一下代码,实现每过一秒钟输出一句话
function fn1(callback) {
setTimeout(()=>{
console.log('fn1')
callback()
}, 1000)
}
function fn2(callback) {
setTimeout(()=>{
console.log('fn2')
callback()
}, 1000)
}
function fn3() {
setTimeout(()=>{
console.log('fn3')
}, 1000)
}
fn1(function(){
fn2(function(){
fn3()
})
})
上面 fn1 里调用fn2,fn2 里调用 fn3 这种就形成了回调地狱,而使用 Promise可以让代码变得更优雅。下面用 Promise 改造
function fn1(){
return new Promise((resolve,reject)=>{
setTeimeout(()=>{
resolve('fn1')
},1000)
})
}
function fn2(){
return new Promise((resolve,reject)=>{
setTeimeout(()=>{
resolve('fn2')
},1000)
})
}
function fn3(){
return new Promise((resolve,reject)=>{
setTeimeout(()=>{
resolve('fn3')
},1000)
})
}
fn1()
.then(fn2)
.then(fn3)
如何手写一个 Promise
我们先考虑如何使用Promise
可以new 一个promise创建一个实例,接收一个函数作为参数,这个函数有两个参数分别是resolve
,reject
const p = new Promise((resolve, reject) => {
//成功回调
resolve(data)
//失败回调
reject(reason)
});
有 then 方法,支持链式调用
p.then(console.log('f1'),console.error('f2'))
.then(console.log('f3'),console.error('f4'))
下面开始手写一个promise
constructor
我们知道new 一个promise实例时,参数fn数是是同步执行的
class MyPromise {
constructor(fn) {
const resolve = (data) => {};
const reject = (reason) => {};
fn.call(undefined, resolve, reject);
}
then(onFulfilled, onRejected) {}
}
console.log(1)
const p = new MyPromise((resolve, reject) => {
console.log("执行了");
});
console.log(2)
一个promise必须处于以下三种状态之一:pending(待定)、fulfilled(实现)或rejected(拒绝),处于pending状态下的promise可以转为fulfilled或者rejected状态,一但状态改变之后,状态就不可变了。这样在我们的promise中添加上状态部分的代码
class MyPromise {
//2.1.1
#status = "pending";
constructor(fn) {
const resolve = (data) => {
//2.1.2.1
if (this.#status !== "pending") return;
this.#status = "fulfilled";
};
const reject = (reason) => {
//2.1.3.1
if (this.#status !== "pending") return;
this.#status = "rejected";
};
fn.call(undefined, resolve, reject);
}
then(onFulfilled, onRejected) {}
}
resolve和reject执行可以传递参数,
下面添参数部分的代码
class MyPromise {
//规范 2.1.1
#status = "pending";
#result = undefined;
constructor(fn) {
const resolve = (data) => {
//规范 2.1.2.1
if (this.#status !== "pending") return;
this.#status = "fulfilled";
//2.1.2.2
this.#result = data;
};
const reject = (reason) => {
//规范 2.1.3.1
if (this.#status !== "pending") return;
this.#status = "rejected";
//2.1.3.2
this.#result = reason;
};
fn.call(undefined, resolve, reject);
}
then(onFulfilled, onRejected) {}
}
还有一种情况,new promise的时候抛出一个错误时,promise状态变为rejected,结果为抛出的错误
所以调用fn是需要try catch处理
class MyPromise {
//规范 2.1.1
#status = "pending";
#result = undefined;
constructor(fn) {
const resolve = (data) => {
//规范 2.1.2.1
if (this.#status !== "pending") return;
this.#status = "fulfilled";
//2.1.2.2
this.#result = data;
};
const reject = (reason) => {
//规范 2.1.3.1
if (this.#status !== "pending") return;
this.#status = "rejected";
//2.1.3.2
this.#result = reason;
};
try {
fn.call(undefined, resolve, reject);
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {}
}
then
then接收两个参数,onFulfilled
和 onRejected
,promise状态为fulfilled时执行onFulfilled回调,状态为rejected时执行onRejected回调,then方法支持链式调用,所以then返回的还是一个promise
class MyPromise {
//规范 2.1.1
#status = "pending";
#result = undefined;
constructor(fn) {
const resolve = (data) => {
//规范 2.1.2.1
if (this.#status !== "pending") return;
this.#status = "fulfilled";
//2.1.2.2
this.#result = data;
};
const reject = (reason) => {
//规范 2.1.3.1
if (this.#status !== "pending") return;
this.#status = "rejected";
//2.1.3.2
this.#result = reason;
};
try {
fn.call(undefined, resolve, reject);
} catch (error) {
this.#result = error;
}
}
then(onFulfilled, onRejected) {
if(this.#status==='fulfilled'){
onFulfilled(this.#result)
}
if(this.#status==='rejected'){
onRejected(this.#result)
}
//2.2.7
return new MyPromise((resolve, reject) => {});
}
}
规范2.2.4 onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用,所以在执行onFulfilled和onRejected时要用异步调用
class MyPromise {
#status = "pending"; //规范2.1.1 初始状态为 pending
#result = undefined; //返回结果
//接收一个 fn 函数,
constructor(fn) {
const resolve = (data) => {
//规范2.1.2 不能转换为其他任何状态
if (this.#status !== "pending") return;
this.#status = "fulfilled"; //规范2.1.2 状态变为 fulfilled
this.#result = data;
};
//规范 2.1.3.2 有一个失败原因
const reject = (reason) => {
//规范2.1.3 不能转换为其他任何状态
if (this.#status !== "pending") return;
this.#status = "rejected"; //2.1.3 状态变为 rejected
this.#result = reason;
};
// 如果函数执行过程中出错,状态变为rejected
try {
fn.call(undefined, resolve, reject);
} catch (error) {
this.reject(error);
}
}
//2.2 有一个 then 方法,// 2.2.1 有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {};
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onRejected = typeof onRejected === "function" ? onRejected : () => {};
//2.2.7 必须返回一个 promise
cosnt p2 = new MyPromise((resolve, reject) => {
if (this.#status === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用
setTimeout(() => {
onFulfilled(this.#result);
});
}
if (this.#status === "rejected") {
setTimeout(() => {
onRejected(this.#result);
});
}
});
}
return p2
}
//测试 输出 1 promise1 4 2
console.log("1");
var p = new MyPromise((resolve, reject) => {
console.log("promise1");
resolve(2);
});
p.then(
(res) => {
console.log(res)
},
() => {
console.log("reject1");
}
);
console.log("4");
测试结果看似没有问题,如果代码稍微改动一下,就有问题了
console.log("1");
var p = new MyPromise((resolve, reject) => {
setTimeout(()=>{
console.log("promise1");
resolve(2);
})
});
p.then(
(res) => {
console.log(res)
},
() => {
console.log("reject1");
}
);
console.log("4");
resolve的结果不输出了,因为then方法中只对
fulfilled
和rejected
的状态做了处理,pending
状态时没有处理,setTimeout中的代码是放到异步任务队列(宏任务)中处理的,运行到p.then时,promise状态始终是pending状态下面在then中加入pending状态的处理
class MyPromise {
#status = "pending"; //规范2.1.1 初始状态为 pending
#result = undefined; //返回结果
//接收一个 fn 函数,
constructor(fn) {
this.queue = [];
this.state = "pending";
const resolve = (data) => {
//规范2.1.2 不能转换为其他任何状态
if (this.state !== "pending") return;
this.state = "fulfilled"; //规范2.1.2 状态变为 fulfilled
this.#result = data;
};
//规范 2.1.3.2 有一个失败原因
const reject = (reason) => {
//规范2.1.3 不能转换为其他任何状态
if (this.state !== "pending") return;
this.state = "rejected"; //2.1.3 状态变为 rejected
this.#result = reason;
};
// 如果函数执行过程中出错,状态变为rejected
try {
// this.queue.push([resolve, reject]);
fn.call(undefined, resolve, reject);
} catch (error) {
reject(error);
}
}
//2.2.1 有一个then方法,有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {};
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onRejected = typeof onRejected === "function" ? onRejected : () => {};
//2.2.7 必须返回一个 promise
const p2 = new MyPromise((resolve, reject) => {
//2.2.2.2 在promise实现之前不得调用它。
if (this.state === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用。
setTimeout((data) => {
onFulfilled(this.#result);
});
}
//2.2.3.2 在promise被拒绝之前不得调用它。
if (this.state === "rejected") {
//2.2.2.1 它必须在promise实现后调用,并以promise的值作为其第一个参数。
setTimeout((reason) => {
onRejected(reason);
});
}
//
if (this.state === "pending") {
}
});
return p2;
}
#resolvePromise(promise, x) {
try {
if (promise === x) {
}
} catch (error) {}
}
}
问题来了,pending状态时要做什么呢?
我们知道hen方法中的onFulfilled
和onRejected
执行时机一定是等promise状态变为fulfilled或者rejected后才执行。也就是说要等到resolve或reject执行之后再执行。很简单,resolve时调用onFulfilled就行了,reject时调用onRejected,
注意then方法支持多次调用,如何多次调用呢,很简单,将onFulfilled和onRejected放入一个队列中,resolve执行时调用所有成功的回调onFulfilled,reject执行时调用所有失败的回调onRejected
class MyPromise {
#status = "pending"; //规范2.1.1 初始状态为 pending
#result = undefined; //返回结果
//接收一个 fn 函数,
constructor(fn) {
this.queue = []; //添加一个队列,存储onFulfilled, onRejected
this.state = "pending";
const resolve = (data) => {
console.log('data:',data)
//规范2.1.2 不能转换为其他任何状态
if (this.state !== "pending") return;
this.state = "fulfilled"; //规范2.1.2 状态变为 fulfilled
this.#result = data;
// 执行resolve时再调用所有onFulfilled
this.queue.map(callbacks=>{
const task = this.queue.shift()
task[0](data)
})
};
//规范 2.1.3.2 有一个失败原因
const reject = (reason) => {
//规范2.1.3 不能转换为其他任何状态
if (this.state !== "pending") return;
this.state = "rejected"; //2.1.3 状态变为 rejected
this.#result = reason;
// 执行reject时再调用所有onRejected
this.queue.map(callbacks=>{
const task = this.queue.shift()
task[1](reason)
})
};
// 如果函数执行过程中出错,状态变为rejected
try {
// this.queue.push([resolve, reject]);
fn.call(undefined, resolve, reject);
} catch (error) {
reject(error);
}
}
//2.2.1 有一个then方法,有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {};
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onRejected = typeof onRejected === "function" ? onRejected : () => {};
//2.2.7 必须返回一个 promise
const p2 = new MyPromise((resolve, reject) => {
//2.2.2.2 在promise实现之前不得调用它。
if (this.state === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用。
setTimeout((data) => {
onFulfilled(this.#result);
});
}
//2.2.3.2 在promise被拒绝之前不得调用它。
if (this.state === "rejected") {
//2.2.2.1 它必须在promise实现后调用,并以promise的值作为其第一个参数。
setTimeout((reason) => {
onRejected(reason);
});
}
//pending状态时,将onFulfilled, onRejected存入队列
if (this.state === "pending") {
this.queue.push([onFulfilled, onRejected]);
}
});
return p2;
}
}
下面测试一下,then方法中的回调成功执行了,但是和正常的promise执行顺序不太一样
console.log("1");
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
console.log("2");
resolve(4);
console.log("3");
});
});
p.then(
(res) => {
console.log('res',res);
},
() => {
console.log("reject1");
}
);
console.log("5");
测试正常promise输出的执行结果
console.log("1");
var p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("2");
resolve(4);
console.log("3");
});
});
p.then(
(res) => {
console.log('res',res);
},
() => {
console.log("reject1");
}
);
console.log("5");
可以看到resolve的执行是在最后执行的。如何让resolve在后面执行呢,很简单放到setTimeout中就行啦
class MyPromise {
#status = "pending"; //规范2.1.1 初始状态为 pending
#result = undefined; //返回结果
//接收一个 fn 函数,
constructor(fn) {
this.queue = []; //添加一个队列,存储onFulfilled, onRejected
const resolve = (data) => {
//规范2.1.2 不能转换为其他任何状态
if (this.#status !== "pending") return;
setTimeout(() => {
this.#status = "fulfilled"; //规范2.1.2 状态变为 fulfilled
this.#result = data;
//2.2.6.1 如果/当promise被实现时,所有相应的onFulfilled回调函数必须按照它们发起then调用的顺序执行。
this.queue.map((callbacks) => {
const task = callbacks[0];
task(data);
});
});
};
//规范 2.1.3.2 有一个失败原因
const reject = (reason) => {
//规范2.1.3 不能转换为其他任何状态
if (this.#status !== "pending") return;
setTimeout(() => {
this.#status = "rejected"; //2.1.3 状态变为 rejected
this.#result = reason;
//2.2.6.2 如果/当promise被拒绝时,所有相应的onRejected回调函数必须按照它们发起then调用的顺序执行。
this.queue.map((callbacks) => {
const task = callbacks[1];
task(reason);
});
});
};
// 如果函数执行过程中出错,状态变为rejected
try {
// this.queue.push([resolve, reject]);
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
//2.2.1 有一个then方法,有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
const onFulfilledcallback =
typeof onFulfilled === "function" ? onFulfilled : () => {};
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
const onRejectedcallback =
typeof onRejected === "function" ? onRejected : () => {};
//2.2.7 必须返回一个 promise
const p2 = new MyPromise((resolve, reject) => {
//2.2.2.2 在promise实现之前不得调用onFulfilled。
if (this.#status === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用。
setTimeout(() => {
try {
onFulfilledcallback(this.#result);
} catch (e) {
reject(e);
}
});
}
//2.2.3.2 在promise被拒绝之前不得调用它。
if (this.#status === "rejected") {
//2.2.2.1 它必须在promise实现后调用,并以promise的值作为其第一个参数。
setTimeout(() => {
try {
onRejectedcallback(this.#result);
} catch (e) {
reject(e);
}
});
}
//2.2.6then方法可以在同一个promise上多次调用。
if (this.#status === "pending") {
this.queue.push([onFulfilled, onRejected]);
}
});
return p2;
}
#resolutionProcedure(promise, x, resolve, reject) {
try {
if (promise === x) {
}
} catch (error) {}
}
}
在测试一下
console.log("1");
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
console.log("2");
resolve(4);
console.log("3");
});
});
p.then(
(res) => {
console.log("resolve", res);
},
(reason) => {
console.log("reject", reason);
}
);
console.log("5");
结果和正常的promise一样了
我们知道then方法中onFulfilled或onRejected可以不是一个函数
var p = new Promise((resolve,reject)=>{
resolve(1)
})
p.then(undefined,reason=>{
console.log(reason)
}).then((res)=>{
console.log(res)
},undefined)
需要再then方法中处理一下resolve
和reject
的返回值
class MyPromise {
...
//2.2.1 有一个then方法,有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (data) => data;
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw reason;
};
//2.2.7 必须返回一个 promise
const p2 = new MyPromise((resolve, reject) => {
//2.2.2.2 在promise实现之前不得调用onFulfilled。
if (this.#status === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用。
setTimeout(() => {
try {
const x = onFulfilled(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
//2.2.7.2 如果onFulfilled或onRejected抛出异常e,则promise2必须以e作为原因被拒绝
reject(e);
}
});
}
//2.2.3.2 在promise被拒绝之前不得调用它。
if (this.#status === "rejected") {
//2.2.2.1 它必须在promise实现后调用,并以promise的值作为其第一个参数。
setTimeout(() => {
try {
const x = onRejected(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
//2.2.7.2 如果onFulfilled或onRejected抛出异常e,则promise2必须以e作为原因被拒绝
reject(e);
}
});
}
//2.2.6then方法可以在同一个promise上多次调用。
if (this.#status === "pending") {
this.queue.push([
() => {
setTimeout(() => {
try {
let x = onFulfilled(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
},
() => {
setTimeout(() => {
try {
let x = onRejected(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
},
]);
}
});
return p2;
}
/**
* 对resolve()、reject() 进行改造增强 针对resolve()和reject()中不同值情况 进行处理
* @param {promise} promise2 promise1.then方法返回的新的promise对象
* @param {[type]} x promise1中onFulfilled或onRejected的返回值
* @param {[type]} resolve promise2的resolve方法
* @param {[type]} reject promise2的reject方法
*/
#resolvePromise(promise2, x, resolve, reject) {
//2.3.1 如果promise和x引用同一个对象,则以TypeError为原因拒绝promise
if (x === promise2) {
return reject(new TypeError("Chaining cycle detected for promise"));
}
//2.3.2 如果x是一个promise,采用其状态
if (x instanceof MyPromise) {
if (x.#status === "pending") {
x.then(
(y) => {
this.#resolvePromise(promise2, y, resolve, reject);
},
() => {
reject(x.#result);
}
);
}
if (x.#status === "fulfilled") {
resolve(x.#result);
}
if (x.#status === "rejected") {
reject(x.#result);
}
}
//2.3.3 否则,如果x是一个对象或函数:
//注意x不能为null
else if (x !== null && (x instanceof Object || typeof x === "function")) {
try {
//2.3.3.2
var then = x.then;
} catch (e) {
//2.3.3.3
reject(e);
}
if (typeof then === "function") {
//定义called表示y,r是否被调用过
let called = false;
//2.3.3.3.4
try {
then.call(
x,
//2.3.3.3.1
(y) => {
//2.3.3.3.3
if (called) return;
this.#resolvePromise(p2, y, resolve, reject);
called = true;
},
//2.3.3.3.2
(r) => {
//2.3.3.3.3
if (called) return;
reject(r);
called = true;
}
);
} catch (e) {
//2.3.3.3.4.1
if (called) return;
//2.3.3.3.4.2
reject(e);
}
} else {
resolve(x);
}
}
//2.3.4 如果x不是对象或函数,则用x来实现promise。
else {
resolve(x);
}
try {
} catch (error) {}
}
}
实现链式调用
上面代码中then方法返回一个promsie,那么onFulFilled和onReject的结果如何处理呢?
参考promise a+规范2.2.7
- 2.2.7.1如果onFulfilled或onRejected返回一个值
x
,则运行Promise Resolution Procedure [[Resolve]](promise2, x)。 - 2.2.7.2 如果onFulfilled或onRejected抛出异常e,则promise2必须以e作为原因被拒绝。
- 2.2.7.3 如果onFulfilled不是一个函数且promise1被实现,则promise2必须以与promise1相同的值被实现。
- 2.2.7.4 如果onRejected不是一个函数且promise1被拒绝,则promise2必须以与promise1相同的原因被拒绝。
这里我们定义个函数resolvePromise(promise,x resolve,reject) 来处理x
,在then方法中分别在不同状态下用resolvePromise方法处理
class MyPromise {
...
//2.2.1 有一个then方法,有两个可选参数
then(onFulfilled, onRejected) {
//2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {};
// 2.2.1.2 如果onRejected不是一个函数,它必须被忽略
//2.2.5 onFulfilled和onRejected必须作为函数被调用(即没有this值
onRejected = typeof onRejected === "function" ? onRejected : () => {};
//2.2.7 必须返回一个 promise
const p2 = new MyPromise((resolve, reject) => {
//2.2.2.2 在promise实现之前不得调用onFulfilled。
if (this.#status === "fulfilled") {
//2.2.4 onFulfilled或onRejected不能在执行上下文堆栈中只包含平台代码之前调用。
setTimeout(() => {
try {
const x = onFulfilled(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
//2.2.7.2 如果onFulfilled或onRejected抛出异常e,则promise2必须以e作为原因被拒绝
reject(e);
}
});
}
//2.2.3.2 在promise被拒绝之前不得调用它。
if (this.#status === "rejected") {
//2.2.2.1 它必须在promise实现后调用,并以promise的值作为其第一个参数。
setTimeout(() => {
try {
const x = onRejected(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
//2.2.7.2 如果onFulfilled或onRejected抛出异常e,则promise2必须以e作为原因被拒绝
reject(e);
}
});
}
//2.2.6then方法可以在同一个promise上多次调用。
if (this.#status === "pending") {
this.queue.push([
() => {
setTimeout(() => {
try {
let x = onFulfilled(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
},
() => {
setTimeout(() => {
try {
let x = onRejected(this.#result);
this.#resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
},
]);
}
});
return p2;
}
/**
* 对resolve()、reject() 进行改造增强 针对resolve()和reject()中不同值情况 进行处理
* @param {promise} promise2 promise1.then方法返回的新的promise对象
* @param {[type]} x promise1中onFulfilled或onRejected的返回值
* @param {[type]} resolve promise2的resolve方法
* @param {[type]} reject promise2的reject方法
*/
#resolvePromise(promise2, x, resolve, reject) {
}
}
按照下面规范实现resolvePromise
/**
* 对resolve()、reject() 进行改造增强 针对resolve()和reject()中不同值情况 进行处理
* @param {promise} promise2 promise1.then方法返回的新的promise对象
* @param {[type]} x promise1中onFulfilled或onRejected的返回值
* @param {[type]} resolve promise2的resolve方法
* @param {[type]} reject promise2的reject方法
*/
#resolvePromise(promise2, x, resolve, reject) {
//2.3.1 如果promise和x引用同一个对象,则以TypeError为原因拒绝promise
if (x === promise2) {
return reject(new TypeError("Chaining cycle detected for promise"));
}
//2.3.2 如果x是一个promise,采用其状态
if (x instanceof MyPromise) {
if (x.#status === "pending") {
x.then(
(y) => {
this.#resolvePromise(promise2, y, resolve, reject);
},
() => {
reject(x.#result);
}
);
}
if (x.#status === "fulfilled") {
resolve(x.#result);
}
if (x.#status === "rejected") {
reject(x.#result);
}
}
//2.3.3 否则,如果x是一个对象或函数:
//注意x不能为null
else if (x !== null && (typeof x === "object" || typeof x === "function")) {
var then;
try {
//2.3.3.2
then = x.then;
if (typeof then === "function") {
//定义called表示y,r是否被调用过
let called = false;
//2.3.3.3.4
try {
then.call(
x,
//2.3.3.3.1
(y) => {
//2.3.3.3.3
if (called) return;
called = true;
this.#resolvePromise(promise2, y, resolve, reject);
},
//2.3.3.3.2
(r) => {
//2.3.3.3.3
if (called) return;
called = true;
reject(r);
}
);
} catch (e) {
//2.3.3.3.4.1
if (called) return;
//2.3.3.3.4.2
reject(e);
}
} else {
resolve(x);
}
} catch (e) {
//2.3.3.3
reject(e);
}
}
//2.3.4 如果x不是对象或函数,则用x来实现promise。
else {
resolve(x);
}
}
下面测试一下
console.log("1");
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
console.log("2");
resolve(4);
console.log("3");
});
});
p.then(
(res) => {
console.log("resolve1", res);
return new MyPromise((resolve, reject) => {
resolve(123);
});
},
(reason) => {
console.log("reject1", reason);
}
).then(
(res) => {
console.log("resolve2", res);
},
(reason) => {
console.log("reject2", reason);
}
);
console.log("5");
可以看到结果和替换成官方Promise的结果一致