源码地址:https://gitee.com/lagou-19-web-paid/practice/tree/master/promise
// Promise 的三个状态
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
/**
* 模拟 原生Promise
*
* @class MyPromise
* @constructor excutor 构造函数,函数接收俩个回调函数,回调函数
*/
class MyPromise {
constructor( excutor ) {
excutor(this.resolve, this.reject)
}
// 默认状态为 pending(等待)
status = PENDING
// 缓存状态值
value = undefined // 成功状态 【参数】
reason = undefined // 失败状态 【原因】
/**
* 成功回调
*
* @see 函数使用箭头函数,可以使 this 指向于当前 MyPromise 对象
*/
resolve = (value) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 fulfilled(成功)
this.status = FULFILLED
// 缓存成功回调 传递的值
this.value = value
}
/**
* 失败回调
*/
reject = (reason) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 rejected(失败)
this.status = REJECTED
// 缓存失败回调 传递的原因
this.reason = reason
}
/**
* then 方法
*
* @params {function} successCallback[成功回调]
* @params {function} failCallback[失败回调]
*/
then ( successCallback, failCallback ) {
if (this.status === FULFILLED) successCallback(this.value)
if (this.status === REJECTED) failCallback(this.reason)
}
}
// 测试当前 MyPromise
let promiseTest = new MyPromise((resolve, reject) => {
resolve('成功')
// reject('失败')
})
// 执行 then 方法
promiseTest.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
// Promise 的三个状态
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
/**
* 模拟 原生Promise
*
* @class MyPromise
* @constructor excutor 构造函数,函数接收俩个回调函数,回调函数
*/
resolve = (value) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 fulfilled(成功)
this.status = FULFILLED
// 缓存成功回调 传递的值
this.value = value
// 执行成功回调
this.successCallback && this.successCallback(this.value)
}
/**
* 失败回调
*/
reject = (reason) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 rejected(失败)
this.status = REJECTED
// 缓存失败回调 传递的原因
this.reason = reason
// 执行失败回调
this.failCallback && this.failCallback(this.reason)
}
/**
* then 方法
*
* @params {function} successCallback[成功回调]
* @params {function} failCallback[失败回调]
*/
then ( successCallback, failCallback ) {
if (this.status === FULFILLED) successCallback(this.value)
else if (this.status === REJECTED) failCallback(this.reason)
else {
// 缓存成功回调
this.successCallback = successCallback
// 缓存失败回调
this.failCallback = failCallback
}
}
}
// 测试当前 MyPromise
let promiseTest = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
// reject('失败')
}, 2000)
})
promiseTest.then((value) => {
console.log('成功回调:', value)
}, (reason) => {
console.log('失败原因:', reason)
})
// Promise 的三个状态
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
/**
* 模拟 原生Promise
*
* @class MyPromise
* @constructor excutor 构造函数,函数接收俩个回调函数,回调函数
*/
class MyPromise {
constructor(excutor) {
excutor(this.resolve, this.reject)
}
// 默认状态为 pending(等待)
status = PENDING
// 缓存状态值
value = undefined // 成功状态 【参数】
reason = undefined // 失败状态 【原因】
// 缓存回调函数
successCallback = [] // 成功回调
failCallback = [] // 失败回调
/**
* 成功回调
*
* @see 函数使用箭头函数,可以使 this 指向于当前 MyPromise 对象
*/
resolve = (value) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 fulfilled(成功)
this.status = FULFILLED
// 缓存成功回调 传递的值
this.value = value
// 执行成功回调
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
/**
* 失败回调
*/
reject = (reason) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 rejected(失败)
this.status = REJECTED
// 缓存失败回调 传递的原因
this.reason = reason
// 执行失败回调
while (this.failCallback.length) this.failCallback.shift()(this.reason)
}
/**
* then 方法
*
* @params {function} successCallback[成功回调]
* @params {function} failCallback[失败回调]
*/
then(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)
}
}
}
// 测试当前 MyPromise
let promiseTest = (status, num) => {
return new MyPromise((resolve, reject) => {
setTimeout(() => {
if (status) resolve(`成功:${num}`)
else reject(`失败:${num}`)
}, 2000)
})
}
promiseTest(true, 1).then((value) => {
console.log('成功回调:', value)
}, (reason) => {
console.log('失败原因:', reason)
})
promiseTest(false, 2).then((value) => {
console.log('成功回调:', value)
}, (reason) => {
console.log('失败原因:', reason)
})
promiseTest(true, 3).then((value) => {
console.log('成功回调:', value)
}, (reason) => {
console.log('失败原因:', reason)
})
// Promise 的三个状态
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
/**
* 模拟 原生Promise
*
* @class MyPromise
* @constructor excutor 构造函数,函数接收俩个回调函数,回调函数
*/
class MyPromise {
constructor(excutor) {
try {
excutor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 默认状态为 pending(等待)
status = PENDING
// 缓存状态值
value = undefined // 成功状态 【参数】
reason = undefined // 失败状态 【原因】
// 缓存回调函数
successCallback = [] // 成功回调
failCallback = [] // 失败回调
/**
* 成功回调
*
* @see 函数使用箭头函数,可以使 this 指向于当前 MyPromise 对象
*/
resolve = (value) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 fulfilled(成功)
this.status = FULFILLED
// 缓存成功回调 传递的值
this.value = value
// 执行成功回调
while (this.successCallback.length) this.successCallback.shift()()
}
/**
* 失败回调
*/
reject = (reason) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 rejected(失败)
this.status = REJECTED
// 缓存失败回调 传递的原因
this.reason = reason
// 执行失败回调
while (this.failCallback.length) this.failCallback.shift()()
}
/**
* then 方法
*
* @params {function} successCallback[成功回调]
* @params {function} failCallback[失败回调]
*/
then(successCallback, failCallback) {
// 回调参数可以为空
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback ? failCallback : reason => { throw reason }
const promiseNext = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
// 当前代码块改变为异步状态,获取到 promiseNext 对象
setTimeout(() => {
try {
// 获取到回调结果
let successNext = successCallback(this.value)
// 执行返回逻辑
resolvePromise(promiseNext, successNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 获取到回调结果
let failNext = failCallback(this.reason)
// 执行返回逻辑
resolvePromise(promiseNext, failNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 缓存成功回调
this.successCallback.push(() => {
setTimeout(() => {
try {
// 获取到回调结果
let successNext = successCallback(this.value)
// 执行返回逻辑
resolvePromise(promiseNext, successNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
// 缓存失败回调
this.failCallback.push(() => {
setTimeout(() => {
try {
// 获取到回调结果
let failNext = failCallback(this.reason)
// 执行返回逻辑
resolvePromise(promiseNext, failNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
// 链式调用,返回新的Promise
return promiseNext
}
}
// 链式调用处理回调函数
function resolvePromise(promise, next, resolve, reject) {
// 禁止返回当前 Promise
if (promise === next) return reject(new TypeError('Chaining cycle detected for promise #' ))
// 判断当前返值状态
if (next instanceof MyPromise) next.then(resolve, reject) // 如果 返回值为 Promise 对象,则获取到返回值,并调用 resolve、reject 方法传递
else resolve(next) // 如果是普通值,则直接调用 resolve 方法
}
// 测试当前 MyPromise
let promiseTest = (status, num) => {
return new MyPromise((resolve, reject) => {
// setTimeout(() => {
if (status) resolve(`成功:${num}`)
else reject(`失败:${num}`)
// }, 2000)
})
}
// 链式调用
promiseTest(true, 1).then((value) => {
console.log('成功回调:', value)
throw Error(value.replace(/成功/, '失败').replace(/[0-9]/g, 2))
}, (reason) => {
console.log('失败原因:', reason)
}).then((value) => {
console.log('成功回调:', value)
return value.replace(/[0-9]/g, 3)
}, (reason) => {
console.log('失败原因:', reason)
return (reason && reason.message || '失败:3').replace(/失败/, '失败 -> 成功').replace(/[0-9]/g, '2 -> 3')
}).then((value) => {
console.log('成功回调:', value)
return value.replace(/[0-9]/g, 4)
}, (reason) => {
console.log('失败原因:', reason)
})
// 参数可选
promiseTest(true, 100).then().then().then((value) => console.log('value', value))
promiseTest(false, -100).then().then().then((value) => console.log(value), (reason) => console.log('reason', reason))
Promise 中的 all 方法
Promise 中的 resolve 方法
Promise 中的 finally 方法
Promise 中的 catch 方法
// Promise 的三个状态
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
/**
* 模拟 原生Promise
*
* @class MyPromise
* @constructor excutor 构造函数,函数接收俩个回调函数,回调函数
*/
class MyPromise {
constructor(excutor) {
try {
excutor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 默认状态为 pending(等待)
status = PENDING
// 缓存状态值
value = undefined // 成功状态 【参数】
reason = undefined // 失败状态 【原因】
// 缓存回调函数
successCallback = [] // 成功回调
failCallback = [] // 失败回调
/**
* 成功回调
*
* @see 函数使用箭头函数,可以使 this 指向于当前 MyPromise 对象
*/
resolve = (value) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 fulfilled(成功)
this.status = FULFILLED
// 缓存成功回调 传递的值
this.value = value
// 执行成功回调
while (this.successCallback.length) this.successCallback.shift()()
}
/**
* 失败回调
*/
reject = (reason) => {
// 状态一旦确定不支持更改,return 出函数
if (this.status !== PENDING) return
// 更改状态为 rejected(失败)
this.status = REJECTED
// 缓存失败回调 传递的原因
this.reason = reason
// 执行失败回调
while (this.failCallback.length) this.failCallback.shift()()
}
/**
* then 方法
*
* @params {function} successCallback[成功回调]
* @params {function} failCallback[失败回调]
*/
then(successCallback, failCallback) {
// 回调参数可以为空
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback ? failCallback : reason => { throw reason }
const promiseNext = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
// 当前代码块改变为异步状态,获取到 promiseNext 对象
setTimeout(() => {
try {
// 获取到回调结果
let successNext = successCallback(this.value)
// 执行返回逻辑
resolvePromise(promiseNext, successNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 获取到回调结果
let failNext = failCallback(this.reason)
// 执行返回逻辑
resolvePromise(promiseNext, failNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 缓存成功回调
this.successCallback.push(() => {
setTimeout(() => {
try {
// 获取到回调结果
let successNext = successCallback(this.value)
// 执行返回逻辑
resolvePromise(promiseNext, successNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
// 缓存失败回调
this.failCallback.push(() => {
setTimeout(() => {
try {
// 获取到回调结果
let failNext = failCallback(this.reason)
// 执行返回逻辑
resolvePromise(promiseNext, failNext, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
// 链式调用,返回新的Promise
return promiseNext
}
/**
* Promise 对象的 finally 方法
*/
finally(callback) {
// 调用 then 方法,获取 Promise 的状态,并返回
return this.then(
// 传递成功值,并把 回调函数包装为 Promise 对象 返回
(value) => MyPromise.resolve(callback()).then(() => value),
// 传递失败原因,并把 回调函数包装为 Promise 对象 返回
(reason) => MyPromise.resolve(callback().then(() => { throw reason })
))
}
/**
* Promise 对象的 then 方法
*/
catch(callback) {
return this.then(undefined, callback)
}
/**
* Promise 对象的 all 方法
*/
static all(array) {
// 缓存最终结果
let result = []
// 缓存结果的
let count = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
function addData(key, value) {
// 按下标缓存最终值
result[key] = value
// 缓存值的次数
count++
// 缓存值的次数,等于 all 形参的长度,则代表所有方法或值都缓存至结果
if (count === array.length) resolve(result)
}
// 循环依次执行
for (let i = 0; i < array.length; i++) {
// 获取当前执行
let current = array[i]
// 异步方法处理
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => resolve(reason))
} else { // 普通值处理
addData(i, current)
}
}
})
}
/**
* Promise 对象的 resolve 方法
*/
static resolve(value) {
if (value instanceof MyPromise) return value // Promise 对象则直接返回
else return new MyPromise(resolve => resolve(value)) // 普通值,则包装为异步方法
}
}
// 链式调用处理回调函数
function resolvePromise(promise, next, resolve, reject) {
// 禁止返回当前 Promise
if (promise === next) return reject(new TypeError('Chaining cycle detected for promise #' ))
// 判断当前返值状态
if (next instanceof MyPromise) next.then(resolve, reject) // 如果 返回值为 Promise 对象,则获取到返回值,并调用 resolve、reject 方法传递
else resolve(next) // 如果是普通值,则直接调用 resolve 方法
}