写了一些示例还有仿源码自己实现一个简单的MyPromise,主要内容都在代码注释中:
class PromiseTest {
static test1() {
const p = new Promise((resolve, reject) => {
// resolve('result1')
reject(new Error('error1'))
})
p.then(result => {
console.log(result)
}, error => {
console.log(error.message)
})
}
static test2() {
const p = new Promise((resolve, reject) => {
resolve('result2')
// reject(new Error('error2'))
})
p.then(result => {
console.log(result)
}).catch(error => {
console.log(error.message)
})
}
static test3() {
const p1 = Promise.resolve(1) // new Promise(resolve => resolve(1))
const p2 = Promise.resolve(2)
const p3 = Promise.resolve(3)
// const p3 = Promise.reject(new Error('3'))
// 有reject时只会打印3,正常是数组[1, 2, 3]
Promise.all([p1, p2, p3]).then(resultArr => {
console.log(resultArr)
}, error => {
console.log(error.message)
})
}
static test4() {
const timePromise = function (delay, id, isReject) {
return new Promise((resolve, reject) => {
setTimeout(function () {
if (isReject) {
reject(new Error('error' + id))
} else {
resolve('result' + id)
}
}, delay)
})
}
const p1 = timePromise(2000, 1)
const p2 = timePromise(1000, 2)
const p3 = timePromise(100, 3, true)
const p4 = timePromise(2000, 4, true)
console.log(Date.now())
// 同时执行多个异步操作,所有都拿到结果后,返回结果数组。
// 如果中间有error抛出,then不会执行,catch中拿到的是第一个被执行的reject
Promise.all([p1, p2, p3, p4]).then(resultArr => {
console.log(resultArr)
console.log(Date.now())
}).catch(error => {
console.log(error.message)
console.log(Date.now())
})
}
static test5() {
const timePromise = function (delay, id, isReject) {
return new Promise((resolve, reject) => {
setTimeout(function () {
if (isReject) {
reject(new Error('error' + id))
} else {
resolve('result' + id)
}
}, delay)
})
}
const p1 = timePromise(2000, 1)
const p2 = timePromise(3000, 2)
const p3 = timePromise(10000, 3, true)
const p4 = timePromise(2000, 4, true)
// 无论成功失败,输出执行最快的那个
Promise.race([p1, p2, p3, p4]).then(resultArr => {
console.log(resultArr)
}).catch(error => {
console.log(error.message)
console.log(Date.now())
})
}
static test6() {
const timePromise = function (delay, id, isReject) {
return (resolve, reject) => {
setTimeout(function () {
if (isReject) {
reject(new Error('error' + id))
} else {
resolve('result' + id)
}
}, delay)
}
}
const p1 = timePromise(2000, 1)
const p2 = timePromise(2000, 2)
const p3 = timePromise(2000, 3, true)
const p4 = timePromise(2000, 4)
// 顺序执行,执行完一个再执行下一个
new Promise(p1).then(r => {
console.log(r)
return new Promise(p2)
}, error => {
console.log(error.message())
return new Promise((p2))
}).then(r => {
console.log(r)
return new Promise(p3)
}, error => {
console.log(error.message)
return new Promise(p3)
}).then(r => {
console.log(r)
return new Promise(p4)
}, error => {
console.log(error.message)
return new Promise(p4)
}).then(r => {
console.log(r)
}, error => {
console.log(error.message)
})
}
static test7() {
function executor (resolve, reject) {
// resolve('my-promise')
reject(new Error('my-promise-error'))
}
new MyPromise(executor).then(r => {
console.log(r)
}, error => {
// 当then中写onRejected的时候,catch不会触发,因为catch对应自己的MyPromise,当中并没有任何地方调用reject方法
console.log('error from then: ' + error)
}).catch(error => {
// 当then中不写onRejected的到时候,catch才会触发
// 实际上,当then中不写onRejected的时候,源码会帮我们生成一个函数 reason => throw reason
// 所以会被try catch捕获到触发reject
console.log('error from catch: ' + error)
})
}
}
// promise 三个状态
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
// 正常resolve的执行顺序
// 1、先执行MyPromise构造函数,也就是走到executor执行
// 2、executor执行时,会走到例子中的resolve函数
// 3、因为resolve中设置了setTimeout,所以会优先执行then
// 4、then中构建了一个新的MyPromise,重复1的步骤
// 5、因为新的MyPromise中没有resolve,所以直接执行完毕,就是往两个cb数组中塞回调函数
// 6、此时需要执行resolve中的setTimeout的部分了,这时候就把'my-promise'传给了then中的回调,打印台就打印了
function MyPromise (executor) {
let that = this
that.status = PENDING
that.value = undefined // fulfilled状态时 返回的信息
that.reason = undefined // rejected状态时 拒绝的原因
that.onFulfilledCallbacks = [] // 存储fulfilled状态对应的onFulfilled函数
that.onRejectedCallbacks = [] // 存储rejected状态对应的onRejected函数
function resolve (value) {
if (value instanceof MyPromise) {
return value.then(resolve, reject)
}
setTimeout(() => {
// 调用resolve 回调对应onFulfilled函数
if (that.status === PENDING) {
// 只能由pending状态 => fulfilled状态 (避免调用多次resolve reject)
that.status = FULFILLED
that.value = value
that.onFulfilledCallbacks.forEach(cb => cb(that.value))
}
})
}
function reject (reason) {
setTimeout(() => {
// 调用reject 回调对应onRejected函数
if (that.status === PENDING) {
// 只能由pending状态 => rejected状态 (避免调用多次resolve reject)
that.status = REJECTED
that.reason = reason
debugger
that.onRejectedCallbacks.forEach(cb => {
cb(that.reason)
})
}
})
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function (onFulFilled, onRejected) {
const that = this
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
if (that.status === PENDING) { // 等待态
return new MyPromise((resolve, reject) => {
that.onFulfilledCallbacks.push(value => {
try {
onFulFilled(value)
// 此处略去大量分支处理
} catch (e) {
reject(e)
}
})
that.onRejectedCallbacks.push(reason => {
try {
onRejected(reason)
// 此处略去大量分支处理
} catch (e) {
reject(e)
}
})
})
}
}
MyPromise.prototype.catch = function (onRejected) {
return this.then(null, onRejected)
}
export default PromiseTest