promise基础用法
let p1 = new Promise((resolve, reject) => {
resolve('成功')
reject('失败')
})
console.log('p1', p1) // 成功
let p2 = new Promise((resolve, reject) => {
reject('失败')
resolve('成功')
})
console.log('p2', p2) // 失败
let p3 = new Promise((resolve, reject) => {
throw('报错')
})
console.log('p3', p3) // 失败
从这段代码的执行,我们可以获取到几个知识点
- 成功会执行resolve函数,失败会执行reject函数
- 状态不可逆,状态一旦变化,后面再更改状态是无效的
- 执行throw等同于执行reject
实现resolve和reject
class myPromise {
promiseResult = "";
constructor(excutor) {
excutor(this.resolve, this.reject)
}
resolve = (value) => {
this.promiseResult = value
this.promiseStatus = 'fulfilled'
console.log('resolve', value)
}
reject = (reason) => {
this.promiseResult = reason;
this.promiseStatus = 'rejected'
console.log('reject', reason)
}
}
let p1 = new myPromise((resolve, reject) => {
resolve('成功')
})
console.log('p1', p1)
状态不可逆
let p1 = new myPromise((resolve, reject) => {
resolve('成功')
reject('失败')
})
console.log('p1', p1)
我们会发现成功和失败都执行,然后最后的状态变成了rejected,显然违背了promise状态的不可逆,按照正常逻辑,此处应该返回的状态应该是成功,那我们怎么改呢,我们知道,promise的初始状态是pending,只有在pending状态才可以变成fulfilled或rejected,一旦状态变成fulfilled或者rejected,那么就不在执行成功或失败的函数了,改造后的代码
class myPromise {
promiseResult = "";
promiseStatus = 'pending';
constructor(excutor) {
excutor(this.resolve, this.reject)
}
resolve = (value) => {
if (this.promiseStatus !== 'pending') return; //状态不可逆
this.promiseResult = value
this.promiseStatus = 'fulfilled'
console.log('resolve', value)
}
reject = (reason) => {
if (this.promiseStatus !== 'pending') return; //状态不可逆
this.promiseResult = reason;
this.promiseStatus = 'rejected'
console.log('reject', reason)
}
}
let p1 = new myPromise((resolve, reject) => {
resolve('成功')
reject('失败')
})
console.log('p1', p1)
throw
throw等同于执行reject,那我们用try/catch改造下
constructor(excutor) {
try{
excutor(this.resolve, this.reject)
}catch(e){
this.reject(e)
}
}
const test3 = new MyPromise((resolve, reject) => {
throw('失败')
})
console.log(test3) // MyPromise { PromiseState: 'rejected', PromiseResult: '失败' }
then
// 马上输出 ”成功“
const p1 = new Promise((resolve, reject) => {
resolve('成功')
}).then(res => console.log(res), err => console.log(err))
// 1秒后输出 ”失败“
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('失败')
}, 1000)
}).then(res => console.log(res), err => console.log(err))
// 链式调用 输出 200
const p3 = new Promise((resolve, reject) => {
resolve(100)
}).then(res => 2 * res, err => console.log(err))
.then(res => console.log(res), err => console.log(err))
上面的代码我们可以得出几个结论
- then接收两个回调,一个成功的回调一个失败的回调
- 当状态为fulfilled执行成功的回调,状态为rejected执行失败的回调
- 当resolve或reject在定时器内,先执行定时器再执行then
- then返回的也是promise,可以链式调用
实现then
then = (onFulfilled, onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
if (this.promiseStatus === 'fulfilled') {
onFulfilled()
} else if (this.promiseStatus === 'rejected') {
onRejected()
}
}
// 马上输出 成功
const p1 = new Promise((resolve, reject) => {
resolve('成功')
}).then(res => console.log(res), err => console.log(err))
定时器
class myPromise {
promiseResult = "";
promiseStatus = 'pending';
onFulfilledArr = []; // 存放成功的回调
onRejectedArr = []; // 存放失败的回调
constructor(excutor) {
try {
excutor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
resolve = (value) => {
if (this.promiseStatus !== 'pending') return; //状态不可逆
this.promiseResult = value
this.promiseStatus = 'fulfilled'
// 执行保存的成功的回调
if(this.onFulfilledArr.length){
this.onFulfilledArr.forEach(fn=>fn(this.promiseResult))
}
}
reject = (reason) => {
if (this.promiseStatus !== 'pending') return; //状态不可逆
this.promiseResult = reason;
this.promiseStatus = 'rejected'
// 执行保存的失败的回调
if(this.onRejectedArr.length){
this.onRejectedArr.forEach(fn=>fn(this.promiseResult))
}
}
then = (onFulfilled, onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
if (this.promiseStatus === 'fulfilled') {
onFulfilled()
} else if (this.promiseStatus === 'rejected') {
onRejected()
} else {
// pending状态,还未执行resolve或reject时吧成功和失败的回调分别存起来
this.onFulfilledArr.push(onFulfilled);
this.onRejectedArr.push(onRejected)
}
}
}
// 马上输出 ”成功“
const p1 = new Promise((resolve, reject) => {
resolve('成功')
}).then(res => console.log(res), err => console.log(err))
// 1秒后输出 ”失败“
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('失败')
}, 1000)
}).then(res => console.log(res), err => console.log(err))
链式调用
then = (onFulfilled, onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
// 既然是链式调用,那么then的返回值一定是一个promise
const result = new myPromise((resolve, reject) => {
// 传入成功或失败的函数名
const handler = (cb) => {
try {
// 拿到成功或失败的返回值做一些处理
const res = cb(this.promiseResult);
if (res === result) {
throw new Error('不能返回自身')
}
if (res instanceof myPromise) {
// 如果返回值是promise
// 如果返回值是promise对象,返回值为成功,新promise就是成功,返回值为失败,新promise就是失败
// 那怎么知道是成功还是失败,只有then回调知道
res.then(resolve, reject)
} else {
resolve(res)
}
} catch (err) {
reject(err)
}
};
if (this.promiseStatus === 'fulfilled') {
handler(onFulfilled)
} else if (this.promiseStatus === 'rejected') {
handler(onRejected)
} else {
this.onFulfilledArr.push(onFulfilled);
this.onRejectedArr.push(onRejected)
}
})
return result
}
微任务
const p1 = new myPromise((resolve, reject) => {
resolve('成功')
}).then(res => console.log(res), err => console.log(err))
console.log(99)
正常结果应该是先输出99,再输出成功,因为then是微任务,会等到当前宏任务执行完才执行then函数里的微任务,这时我们只需要把then函数内的handler处理函数改成定时器就行了,因为定时器是宏任务,会等到前一个宏任务及其下面的微任务执行完再执行下一个宏任务,上代码
then = (onFulfilled, onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
// 既然是链式调用,那么then的返回值一定是一个promise
let result
result = new myPromise((resolve, reject) => {
// 传入成功或失败的函数名
const handler = (cb) => {
setTimeout(() => {
try {
// 拿到成功或失败的返回值做一些处理
const res = cb(this.promiseResult);
if (res === result) {
throw new Error('不能返回自身')
}
if (res instanceof myPromise) {
// 如果返回值是promise
// 如果返回值是promise对象,返回值为成功,新promise就是成功,返回值为失败,新promise就是失败
// 那怎么知道是成功还是失败,只有then回调知道
res.then(resolve, reject)
} else {
resolve(res)
}
} catch (err) {
reject(err)
}
})
};
if (this.promiseStatus === 'fulfilled') {
handler(onFulfilled)
} else if (this.promiseStatus === 'rejected') {
handler(onRejected)
} else {
this.onFulfilledArr.push(onFulfilled);
this.onRejectedArr.push(onRejected)
}
})
return result
}
其他方法
all
所有的promise都成功,所有成功的回调放入一个数组返回,如果有一个promise失败,就会返回这个失败的回调
static all = (promises) => {
let result = []
let count = 0;
return new myPromise((resolve, reject) => {
promises.forEach((fn, index) => {
if (fn instanceof myPromise) {
fn.then = res => {
result[index] = res;
count++
}
} else {
result[index] = res;
count++
}
})
if (count === promises.length) {
resolve(result)
}
})
}
any
// 只要有任意一个promise成功就返回这个成功的回调,如果所有的promise都失败,就返回失败
static any = (promises) => {
return new myPromise((resolve, reject) => {
let count = 0;
promises.forEach(promise => {
// if (promise instanceof myPromise) {
promise.then((res) => {
resolve(res);
}, err => {
count++;
if (count === promises.length) {
reject('all rejected')
}
})
// }else{
// resolve(promise)
// }
})
})
race
// 哪个promise最先返回结果,就直接返回这个结果,无论成功失败 static race = (promises) => { return new myPromise((resolve, reject) => { promises.forEach(promise => { if (promise instanceof myPromise) { promise.then(res => { resolve(res) }, err => { reject(err) }) } else { resolve(promise) } }) }) }
allsettled
// 返回所有的promise结果,无论是成功还是失败
static allsettled = (promises) => {
return new myPromise((resolve, reject) => {
const result = [];
let count = 0;
const handler = (status, value, index) => {
result[index] = { status, value };
count++;
if (count === promises.length) {
resolve(result)
}
}
promises.forEach((promise,index) => {
if (promise instanceof myPromise) {
promise.then(res => handler('fulfilled', res, index), err => handler('rejected', err, index))
} else {
handler('fulfilled', promise, index)
}
})
})
}