Promise之前,异步请求的处理方式
使用回调函数的方式的弊端:
1. 如果是我们自己封装的requestData,那么我们在封装的时候必须要自己设计好callback名称,并且使用好
2. 如果我们使用的是别人封装的requestData或者一些第三方库,那么我们必须去看别人的源码或者文档,才知道它这个函数需要怎么去获取到结果
// 以前解决异步请求的处理方式
function requestData(url, successCallback, failtureCallback) {
// 模拟网络请求
setTimeout(() => {
// 拿到请求结果
if(url === 'coder') {
// url是coder请求成功
const names = ['abc','cba','nba']
successCallback(names)
}else {
// 否则失败
const errMessage = '请求失败,url错误'
failtureCallback(errMessage)
}
}, 3000)
}
requestData('coder',(res) => {
console.log(res);
},err => {
console.log(err);
})
Promise的基本使用
在通过new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor
这个回调函数会被立即执行,并且给传入另外两个回调函数resolve,reject
当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数
当我们调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数
function foo() {
return new Promise((resolve,reject) => {
resolve()
reject()
})
}
// main.js
const fooPromise = foo()
// then方法传入的两个回调函数,
// 第一个回调函数,会在Promise执行resulve函数时,被回调
// 第二个回调函数,会在Promise执行reject函数时,被回调
fooPromise.then((res) => {
console.log(res);
}, (err) => {
console.log(err);
})
class Person {
constructor(callback) {
let foo = function(){}
let bar = function(){}
callback(foo, bar)
}
}
const p = new Person((boo,bar) => {
boo()
bar()
})
// 传入的这个函数,称之为executor
// > resolve: 回调函数, 在成功时,调用resolve函数
// > reject: 回调函数, 在失败时,回调reject函数
const promise = new Promise((resolve, reject) => {
console.log('Promise传入的函数被立即执行了');
resolve() // 成功
reject() // 失败
})
promise.then()
异步请求的Promise
// 以前解决异步请求的处理方式
function requestData(url) {
return new Promise((resolve,reject) => {
// 模拟网络请求
setTimeout(() => {
// 拿到请求结果
if(url === 'coder') {
// url是coder请求成功
const names = ['abc','cba','nba']
resolve(names)
}else {
// 否则失败
const errMessage = '请求失败,url错误'
reject(errMessage)
}
}, 3000)
})
}
const promise = requestData('coder')
promise.then((res) => {
console.log('请求成功:',res);
}, (err) => {
console.log('请求失败:',err);
})
Promise的三种状态
Promise使用过程,我们可以将它划分成三个状态
注意: 状态一旦确定下来,那么就是不可更改的
1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝, 当执行executor中的代码时,处于该状态
2. 已兑现(fulfilled, resolved): 意味着操作成功完成, 执行resolve时,处于该状态
3. 已拒绝(rejected): 意味着操作失败; 执行reject时,处于该状态
const promise = new Promise((resolve,reject) => {
})
promise.then(res => {}, err=> {})
// 完全等价于下面的代码
// Promise使用过程,我们可以将它划分成三个状态
/**
* 1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝, 当执行executor中的代码时,处于该状态
* 2. 已兑现(fulfilled, resolved): 意味着操作成功完成, 执行resolve时,处于该状态
* 3. 已拒绝(rejected): 意味着操作失败; 执行reject时,处于该状态
* 4. 注意: 状态一旦确定下来,那么就是不可更改的
* **/
new Promise((resolve, reject) => {
// pending状态
console.log('--------');
resolve() // 处于fulfilled状态
// reject() // 处于reject状态
}).then(res => {
console.log('res:',res);
}, err => {
console.log('err:',err);
})
Promise的resolve参数
/**
* resolve参数
* 1. 传入普通的值,或者对象 pending -> fulfilled
* 2. 传入一个Promise
* 那么当前的Promise的状态会由传入的Promise来决定
* 相当于进行了移交
* 3. 传入一个对象,并且这个对象有一个then方法(并且这个对象是实现了thenable接口)
* 那么也会执行该then方法,并且由该then方法决定后续状态
* **/
// 2.传入Promise的特殊情况
const newPromise = new Promise((resolve,reject) => {
// resolve('aaaaa')
reject('err message')
})
new Promise((resolve,reject) => {
// resolve() // 第一种
resolve(newPromise) // 第二种
}).then(res => {
console.log('res:', res);
},err => {
console.log('err:', err);
})
// 3. 传入一个对象,这个兑现由then方法
new Promise((resolve,reject) => {
// pending -> fulfilled
const obj = {
then: function(resolve,reject) {
// resolve('resulve message')
reject('reject message')
}
}
resolve(obj)
}).then(res => {
console.log('res:', res);
},err => {
console.log('err:', err);
})
Promise对象的then方法
Promise对象上的方法,是在Promise.prototype上的方法
// Promise 有那些对象方法
// console.log(Object.getOwnPropertyDescriptors(Promise.prototype));
const promise = new Promise((resolve,reject) => {
resolve('hahaha')
})
// 1. 同一个promise可以被多次调用then方法
// 当我们的resolve方法被回调时,所有的then方法传入的回调都会被调用
promise.then(res => {
console.log('被调用的第一个',res);
})
promise.then(res => {
console.log('被调用的第二个',res);
})
promise.then(res => {
console.log('被调用的第三个',res);
})
// 2.then方法传入的 ”回调函数: 可以有返回值“
// then方法本身也是有一个返回值, 它的返回值是Promise
// 1. > 如果我们返回的是一个普通值,那么这个普通的值被作为一个新的Promise的resolve值
promise.then(res => {
return 11111
// 上面的操作,在内部其实做的是下面的操作
// return new Promise(resolve => resolve(11111))
}).then(res => {
// 这里获取到的值,是上面then返回的值
console.log('res:', res); // 11111
})
// 2. > 如果我们返回的是一个Promise
promise.then(res => {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(11111)
},3000)
})
}).then(res => {
console.log('res:', res); // res: 11111
})
// 3. > 如果我们返回的是一个对象,并且该对象实现了thenable
promise.then(res => {
return {
then: function(resolve,reject) {
resolve(22222)
}
}
}).then(res => {
console.log('res:', res); // res: 22222
})
Promise对象的catch方法
const promise = new Promise((resolve,reject) => {
// reject('rejected status')
throw new Error('rejected status')
})
// 1. 当executor抛出异常时,也会调用错误(拒绝)捕获的回调函数的
promise.then(undefined, err => {
console.log('err:',err);
})
// 2.通过catch方法来传入错误(拒绝)捕获的回调函数
// 这种写法是不符合 promise/ a+规范
promise.catch(err => [
console.log('err:', err)
])
// 第三种写法
promise.then(res => {
return new Promise(reject => {
reject('then rejected status')
})
}).catch(err=> {
// 这里的catch 最先捕获的是最外层抛出的异常
console.log('err:', err);
})
// 拒绝捕获的问题
const promise = new Promise((resolve,reject) => {
reject('1111')
})
// 此是这里会直接报错,因为这时的这两个函数想当于独立调用,第一个函数,没有写接收异常的处理函数
promise.then(res => {
console.log(res);
})
promise.catch(err => {
console.log(err);
})
// catch方法的返回值
const promise = new Promise((resolve,reject)=> {
reject('11111')
})
promise.then(res => {
console.log('res:',res);
}).catch(err => {
return 'catch return value' // 这里的返回值跟then里是一样的,都是通过resolve返回一个promise
}).then(res => {
console.log('res result:', res);
}).catch(err => {
console.log('err result:', err);
})
Promise对象的finally方法
const promise = new Promise((resolve, reject) => {
resolve('resolve message')
})
promise.then(res => {
console.log('res:', res);
}).catch(err=> {
console.log('err:',err);
}).finally(() => {
// 这里的代码是一定会执行的
console.log('finally code execute');
})
Promise类的resolve方法
// 类方法Promise.resolve
const promise = Promise.resolve({name: 'coder'})
// 相当于
const promise2 = new Promise(resolve=> resolve({name: 'coder'}))
// 2.传入Promise
const promise3 = Promise.resolve(new Promise(resolve => resolve('123456789')))
promise3.then(res => {
console.log('res:',res); // 123456789
})
// 3.传入thenable对象
const obj = {
then: function(resolve) {
resolve('123456789')
}
}
const promise4 = Promise.resolve(new Promise(resolve => resolve(obj)))
promise3.then(res => {
console.log('res:',res); // 123456789
})
Promise类的reject方法
const promise = Promise.reject('rejected message')
// 相当于
const promise2 = new Promise(reject => reject('rejected message'))
// 注意: 无论传入什么值都是一样的
const promise3 = Promise.reject(new Promise(resolve => resolve('12345678')))
promise3.then(res => {
console.log("res:",res);
}).catch(err=> {
console.log('err:',err); // err: Promise { '12345678' }
})
Promise类的all方法
// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(111)
},1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(222)
},2000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(333)
},3000)
})
// 所有的Promise都变成fulfilled时,再拿到结果
// 意外: 在拿到所有结果之前,有一个promise变成了rejected,那么整个promise是rejected
Promise.all([p2, p1,p3,'aaaa']).then(res => {
console.log(res); // [ 222, 111, 333, 'aaaa' ]
}).catch(err => {
console.log('err:',err);
})
Promise类的allSettled方法
// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(111)
},1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(222)
},2000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(333)
},3000)
})
// allSettled 会等所有的都有结果后返回所有的结果
Promise.allSettled([p2,p1,p3]).then(res => {
console.log(res);
/**
* [
{ status: 'fulfilled', value: 222 },
{ status: 'fulfilled', value: 111 },
{ status: 'fulfilled', value: 333 }
]
* **/
}).catch(err => {
console.log('err:',err);
})
Promise类的case方法
// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(111)
},1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(222)
},2000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(333)
},3000)
})
// race 竞技/竞赛
// 当几个promise有一个resovled结果时,就会返回结果
// 意外,当在resolved之前,有一个rejected,会直接变成rejected
const promise = Promise.race([p1,p2,p3])
promise.then(res => {
console.log(res); // 111
}).catch(err => {
console.log(err);
})
Promise类的any方法
// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(111)
},1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
reject(222)
},200)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(333)
},500)
})
// any方法
// 只有当有resolve有结果的时候才会打印结果,
// 当所有promise都是rejected时,才会进入catch
Promise.any([p1,p2,p3]).then(res => {
console.log(res); // 333
}).catch(err=> {
console.log('err:',err.errors);
})
手写一个Promise
1. 结构的设计
// Promise A+规范地址 https://promiseaplus.com/
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
const resolve = (value) => {
if(this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED
this.value = value
console.log('resolve被调用');
// 这里还要执行then传入的第一个回调函数
}
}
const reject = (reason) => {
if(this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
console.log('reject被调用');
// 这里还要执行then传入的第二个回调函数
}
}
executor(resolve,reject)
}
}
const promise = new HPromise((resolve,reject) => {
console.log('状态pending');
resolve(1111)
})
then方法设计
// Promise A+规范地址 https://promiseaplus.com/
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
const resolve = (value) => {
if(this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED
// queueMicrotask把一个函数加到微任务当中
queueMicrotask(() => {
this.value = value
this.onFulfilled(this.value)
})
}
}
const reject = (reason) => {
if(this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
queueMicrotask(() => {
this.reason = reason
this.onFulfilled(this.reason)
})
}
}
executor(resolve,reject)
}
then(onFulfilled, onRejected) {
this.onFulfilled = onFulfilled
this.onRejected = onRejected
}
}
const promise = new HPromise((resolve,reject) => {
console.log('状态pending');
resolve('1111')
reject('22222')
})
promise.then(res => {
console.log('res:',res);
},err => {
console.log('err:',err);
})
then方法优化一
优化当状态确认后的then调用
// Promise A+规范地址 https://promiseaplus.com/
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if(this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if(this.status !== PROMISE_STATUS_PENDING)return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn(this.value))
})
}
}
const reject = (reason) => {
if(this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if(this.status !== PROMISE_STATUS_PENDING)return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn(this.reason))
})
}
}
executor(resolve,reject)
}
// then方法实现
then(onFulfilled, onRejected) {
// 当状态已经确定,就直接执行传入的函数
if(this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
onFulfilled(this.value)
}
// 当状态已经确定,就直接执行传入的函数
if(this.status === PROMISE_STATUS_REJECTED && onRejected) {
onRejected(this.reason)
}
if(this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(onFulfilled)
this.onRejectedFns.push(onRejected)
}
}
}
const promise = new HPromise((resolve,reject) => {
console.log('状态pending');
resolve('1111')
reject('22222')
})
// 多次then的调用
promise.then(res => {
console.log('res1:',res);
},err => {
console.log('err1:',err);
})
promise.then(res => {
console.log('res2:',res);
},err => {
console.log('err2:',err);
})
// 在确定promise状态后,再次调用
setTimeout(() => {
promise.then(res => {
console.log('res3:',res);
},err => {
console.log('err3:',err);
})
},1000)
then方法优化二
实现then方法的链式调用
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
}
const promise = new HPromise((resolve, reject) => {
console.log('状态pending');
resolve('1111')
// reject('22222')
})
promise.then(res => {
console.log('res:', res);
// throw new Error('错误异常')
return 'aaaa'
}, err => {
console.log('err:', err);
}).then(res => {
console.log('res1:', res);
return 'bbbb'
}, err => {
console.log('err1:', err);
}).then(res => {
console.log('res2:', res);
}, err => {
console.log('err2:', err);
})
catch方法设计
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
// 判断当前then方法有没有处理异常,如果没有处理,交给后面的方法(then,catch)处理
onRejected = onRejected || (err => {throw err})
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
onFulfilled && this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
onRejected && this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
// catch方法的实现
catch(onRejected) {
this.then(undefined,onRejected)
}
}
const promise = new HPromise((resolve, reject) => {
console.log('状态pending');
resolve('1111')
// reject('22222')
})
promise.then(res => {
console.log('res:', res);
throw new Error('错误异常')
return 'aaaa'
}, err => {
console.log('err1:', err);
}).catch(err => {
console.log('err:',err);
})
finally方法设计
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
// 判断当前有没有传进来两个函数
onRejected = onRejected || (err => { throw err })
onFulfilled = onFulfilled || (value => value)
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
// catch方法的实现
catch(onRejected) {
// 给catch返回一个promise
return this.then(undefined, onRejected)
}
// finally方法的实现
finally(onFinally) {
// 把当前finally要执行的函数传进去
this.then(() => onFinally(), () => onFinally())
}
}
const promise = new HPromise((resolve, reject) => {
console.log('状态pending');
resolve('1111')
// reject('22222')
})
promise.then(res => {
console.log('res:', res);
// throw new Error('错误异常')
return 'aaaa'
}).catch(err => {
console.log('err:', err);
}).finally(() => {
console.log('finally');
})
Promise类方法 resolve reject
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
// 判断当前有没有传进来两个函数
onRejected = onRejected || (err => { throw err })
onFulfilled = onFulfilled || (value => value)
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
// catch方法的实现
catch(onRejected) {
// 给catch返回一个promise
return this.then(undefined, onRejected)
}
// finally方法的实现
finally(onFinally) {
// 把当前finally要执行的函数传进去
this.then(() => onFinally(), () => onFinally())
}
static resolve(value) {
return new HPromise(resovle => resovle(value))
}
static reject(season) {
return new HPromise(reject => reject(season))
}
}
HPromise.resolve('Hello World').then(res => {
console.log('res:',res);
})
HPromise.reject('Error Message').then(err => {
console.log('err:',err);
})
Promise类方法 all allSettled
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
// 判断当前有没有传进来两个函数
onRejected = onRejected || (err => { throw err })
onFulfilled = onFulfilled || (value => value)
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
// catch方法的实现
catch(onRejected) {
// 给catch返回一个promise
return this.then(undefined, onRejected)
}
// finally方法的实现
finally(onFinally) {
// 把当前finally要执行的函数传进去
this.then(() => onFinally(), () => onFinally())
}
static resolve(value) {
return new HPromise(resovle => resovle(value))
}
static reject(season) {
return new HPromise(reject => reject(season))
}
static all(parmises) {
// 问题关键: 什么时候执行resolve,什么时候执行reject
const values = []
return new HPromise((resolve, reject) => {
parmises.forEach(parmise => {
parmise.then(res => {
values.push(res)
if (values.length === parmises.length) {
resolve(res)
}
}, err => {
reject(err)
})
})
})
}
// 只有当所有的promise都有返回值后,才会再resolve里拿到所有的结果和状态
static allSettled(parmises) {
return new HPromise(resolve => {
const values = []
parmises.forEach(parmise => {
parmise.then(res => {
values.push({status: PROMISE_STATUS_FULFILLED,value:res})
if(values.length === parmises.length) {
resolve(values)
}
},err => {
values.push({status: PROMISE_STATUS_REJECTED,value:err})
if(values.length === parmises.length) {
resolve(values)
}
})
})
})
}
}
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(333)
}, 3000)
})
// Promise.all([p2, p1, p3]).then(res => {
// console.log('res:', res);
// }).catch(err => {
// console.log('err:', err);
// })
Promise.allSettled([p1,p2,p3]).then(res => {
console.log('res:',res);
},err => {
console.log('err:',err);
})
Promise类方法 any race
// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
try {
const result = fn(value)
resolve(result)
} catch (error) {
reject(error)
}
}
class HPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING // 整个promise的状态
this.value = undefined // resolve接受的参数
this.reason = undefined // reject接受的参数
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => fn())
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
// 先判断状态是否是pending状态,如果不是就不再执行下面的代码
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => fn())
})
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法实现
then(onFulfilled, onRejected) {
// 判断当前有没有传进来两个函数
onRejected = onRejected || (err => { throw err })
onFulfilled = onFulfilled || (value => value)
return new HPromise((resolve, reject) => {
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_FULFILLED) {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 当状态已经确定,就直接执行传入的函数
if (this.status === PROMISE_STATUS_REJECTED) {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
execFnWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
execFnWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
// catch方法的实现
catch(onRejected) {
// 给catch返回一个promise
return this.then(undefined, onRejected)
}
// finally方法的实现
finally(onFinally) {
// 把当前finally要执行的函数传进去
this.then(() => onFinally(), () => onFinally())
}
static resolve(value) {
return new HPromise(resovle => resovle(value))
}
static reject(season) {
return new HPromise(reject => reject(season))
}
static all(parmises) {
// 问题关键: 什么时候执行resolve,什么时候执行reject
const values = []
return new HPromise((resolve, reject) => {
parmises.forEach(parmise => {
parmise.then(res => {
values.push(res)
if (values.length === parmises.length) {
resolve(res)
}
}, err => {
reject(err)
})
})
})
}
// 只有当所有的promise都有返回值后,才会再resolve里拿到所有的结果和状态
static allSettled(parmises) {
return new HPromise(resolve => {
const values = []
parmises.forEach(parmise => {
parmise.then(res => {
values.push({ status: PROMISE_STATUS_FULFILLED, value: res })
if (values.length === parmises.length) {
resolve(values)
}
}, err => {
values.push({ status: PROMISE_STATUS_REJECTED, value: err })
if (values.length === parmises.length) {
resolve(values)
}
})
})
})
}
// 当几个promise有一个resovled结果时,就会返回结果
// 意外,当在resolved之前,有一个rejected,会直接变成rejected
static race(parmises) {
return new HPromise((resolve, reject) => {
parmises.forEach(parmise => {
// parmise.then(res => resolve(res), err=> reject(err))
parmise.then(resolve, reject)
})
})
}
// any方法
// 只有当有resolve有结果的时候才会打印结果,
// 当所有promise都是rejected时,才会进入catch
static any(parmises) {
const reasons = []
return new HPromise((resolve,reject) => {
parmises.forEach(parmise => {
parmise.then(resolve, err => {
reasons.push(err)
if(reasons.length === parmises.length) {
reject(new AggregateError(reasons))
}
})
})
})
}
}
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(111)
}, 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(333)
}, 3000)
})
// HPromise.race([p1, p2, p3]).then(res => {
// console.log('res:', res);
// }, err => {
// console.log('err:', err);
// })
HPromise.any([p1, p2, p3]).then(res => {
console.log('res:', res);
}, err => {
console.log('err:', err.errors);
})