一、Promie 类基本核心逻辑实现
const p = new Promise((resolve, reject) => {
resolve('成功')
});
p.then((data) => {
console.log('resolved',data);
},(err) => {
console.log('rejected',err);
});
以上是 Promise 的基本使用,可以得知
- Promise 就是一个类,在执行这个类的时候,需要传递一个执行器进去,并且执行器会立即执行
- Promise 中有三种状态,分别为成功 fulfilled 失败 rejected 等待 pending
- Promise 的状态默认 pending,是只能被修改一次,一旦被修改就不可修改,只能从 pending 改成 fulfilled,或者是从 pending 改成 rejected
- 传递给执行器的两个方法 resolve 和 reject 函数都是用来更改状态的,resolve 把状态变成 fulfilled,reject 把状态变成 rejected
- then 方法内部做的事情就判断状态,如果状态是成功,调用成功的回调函数,如果状态是失败,调用失败回调函数,then方法是被定义在原型对象中的,then 成功回调有一个参数,表示成功之后的值,then 失败回调有一个参数,表示失败后的原因
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
}
then(successCallback, failCallback) {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
successCallback(this.value)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
}
}
二、在 Promie 类中加入对异步逻辑的处理
const p = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('成功')
}, 2000)
});
p.then((data) => {
console.log('resolved',data);
},(err) => {
console.log('rejected',err);
});
因为上述代码中执行器中的代码是异步执行的,没有立即调用 resolve,导致 then 方法执行的时候状态还是 promise 的状态还是 pending,所以我们要先把 then 方法中成功和失败的回调保存起来,在执行器执行 resolve 或者 reject 的时候,判断是否存在相对应的回调函数,如果有就执行
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = undefined;
// 失败回调
failCallback = undefined;
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就调用
this.successCallback && this.successCallback(value)
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就调用
this.failCallback && this.failCallback(reason)
}
then(successCallback, failCallback) {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
successCallback(this.value)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback = successCallback
this.failCallback = failCallback
}
}
}
三、实现 then 方法多次调用添加多个处理函数
const p = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('成功')
}, 2000)
});
p.then(value => { console.log('1', value) })
p.then(value => { console.log('1', value) })
p.then(value => { console.log('1', value) })
上述代码中,then 方法被调用了三次,有三个成功的回调函数,所以说 promise 必须用数组来保存成功和失败的回调,等到 resolve 或者 reject,再将数组中的回调函数循环执行
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()(value)
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()(reason)
}
}
then(successCallback, failCallback) {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
successCallback(this.value)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
}
}
四、实现 then 方法的链式调用
const p = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('成功')
}, 2000)
});
p.then(value => {
console.log(value)
return 100
}).then(value => {
console.log(value) // 100
})
在上述代码中 then 方法被链式调用了,也就是说 then 方法返回的是一个 Promise 的实例对象,并且下一个 then 方法拿到的值,是上一个 then 方法回调函数的返回值,所以说在执行 then 方法的时候必须 new 一个 Promise 的实例对象,并且将判断逻辑写到这个这个 promise 对象的执行器中,如果上一个 promise 对象的状态为 fulfilled ,则获取上一个 promise 对象成功回调的返回值,传给下一个 then 的回调函数
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()(value)
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()(reason)
}
}
then(successCallback, failCallback) {
// 创建一个 promise 对象
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
// 获取回调函数的返回值
let x = successCallback(this.value)
// 将回调函数的值传递给下一个 then 的回调函数
resolve(x)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
const p = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('成功')
}, 2000)
});
p.then(value => {
console.log(value)
return new Promise((resolve, reject) => { resolve('100') })
}).then(value => {
console.log(value) // 100
})
上述代码中,第一次 then 方法回调函数返回的不是一个普通值,而是一个 promise 对象,所以就得先去查看这个 promise 对象的状态,如果状态是成功的话,就调用这个 promise 对象的 resolve 方法,把这个成功的状态传递给下一个 promise 对象,如果状态是失败的,就得调用它的 reject 方法,把失败的状态传递给下一个 promise 对象,这里我们就定义一个方法来判断第一次 then 方法中回调函数的返回值究竟是 promise 对象还是普通值
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()(value)
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()(reason)
}
}
then(successCallback, failCallback) {
// 创建一个 promise 对象
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
// 获取回调函数的返回值
let x = successCallback(this.value)
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象 查看 promsie 对象返回的结果
// 再根据 promise 对象返回的结果 决定调用 resolve 还是调用 reject
resolvePromise(x, resolve, reject)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
function resolvePromise(x, resolve, reject) {
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
五、实现 then 方法链式调用识别 Promie 对象自返回情况
const p = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('成功')
}, 2000)
});
const p1 = p.then(value => {
console.log(value)
return p1
})
p1.then(value => {
console.log(value)
})
上述代码中出现了在 then 方法的回调函数中返回了当前这个 then 方法返回的 promise 对象的情况,出现这种情况会导致浏览器死机的,因为如果在当前 then 方法的回调函数中返回的 promise 对象和 then 方法返回的 promise 对象一样,就会导致 promise 对象的循环调用,所以就得做判断,将当前要返回的 promise 对象传进去,和将要执行的 promise 对象做对比,如果出现自调用的情况,就抛出异常
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()(value)
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()(reason)
}
}
then(successCallback, failCallback) {
// 创建一个 promise 对象
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 获取回调函数的返回值
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
else if (this.status === REJECTED) {
failCallback(this.reason)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
function resolvePromise(promsie2, x, resolve, reject) {
// 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
if (promsie2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
六、then 链式调用失败和等待状态处理
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()()
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()()
}
}
then(successCallback, failCallback) {
// 创建一个 promise 对象
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 获取回调函数的返回值
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 获取回调函数的返回值
let x = failCallback(this.reason)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}); s
}
})
return promise2
}
}
function resolvePromise(promsie2, x, resolve, reject) {
// 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
if (promsie2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
七、将 then 方法的参数变成可选参数
在 then 方法中不传递任何参数的时候就等同于 then(value=>value) 这样就可以将状态传递下去
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
// 接收执行器,并且立即执行
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
// 如果执行器报错,则执行 reject
this.reject(e);
}
}
// promsie 状态 ,默认值是 pending
status = PENDING
// 成功之后的值
value = undefined
// 失败后的原因
reason = undefined
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = (value) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 fulfilled
this.status = FULFILLED
// 保存成功之后的值
this.value = value
// 判断成功回调是否回调,如果存在就依次调用
while (this.successCallback.length) {
// 从前往后执行
this.successCallback.shift()()
}
}
reject = (reason) => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为 rejected
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否回调,如果存在就依次调用
while (this.failCallback.length) {
// 从前往后执行
this.failCallback.shift()()
}
}
then(successCallback, failCallback) {
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback : reason => { throw reason };
// 创建一个 promise 对象
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 获取回调函数的返回值
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 获取回调函数的返回值
let x = failCallback(this.reason)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
else {
// 当前状态为等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}); s
}
})
return promise2
}
}
function resolvePromise(promsie2, x, resolve, reject) {
// 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
if (promsie2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
八、Promise.all 方法实现
- Promise.all 是 Promise 的类方法,用于将多个 Promise 实例,包装成一个新的 Promise 实例
- Promise.all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
- Promise.all 方法是用来解决异步并发问题的,允许我们通过异步代码调用的顺序,得到异步代码运行的结果
static all(array) {
let result = []; // 存放结果
let index = 0; // 计数器,当 index 等于 array.length 说明所有异步任务执行完成
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接返回
addData(i, array[i]);
}
}
})
}
九、Promie.reolve 方法的实现
- Promise.resolve(value)返回一个以 value 值解析后的 Promise 对象
- Promise.resolve 如果是普通值,返回值就是一个 promise 对象,并且调用了 resolve()
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value));
}
十、finally 方法的实现
不管这个 promise 对象最终的状态是成功还是失败,finally 方法都会被执行一次,在 finally 方法后面可以链式调用 then 方法,获取当前这个 promise 对象最终返回的结果
finally(callback) {
// 通过 this.then 来获取当前 promise 的状态
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value);
}, reason => {
return MyPromise.resolve(callback()).then(() => { throw reason })
})
}
十一、catch 方法的实现
catch(failCallback) {
return this.then(undefined, failCallback)
}