class MyPromise {
constructor(func) {
const resolve = (result) => {
console.log('run', result)
}
const reject = (result) => {
console.log('run', reject)
}
func(resolve, reject)
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject)=> {
resolve('success')
// reject('error')
})
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
state = PENDING
result = undefined
constructor(func) {
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
}
}
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
}
}
func(resolve, reject)
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
resolve('success')
reject('error')
})
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
state = PENDING
result = undefined
constructor(func) {
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
}
}
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
}
}
func(resolve, reject)
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled: x => x
onRejected = typeof onRejected === 'function'? onRejected: x => {throw x}
if (this.state === FULFILLED) {
onFulfilled(this.result);
} else if (this.state === REJECTED) {
onRejected(this.result);
}
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
// resolve('success')
reject('error111')
})
p.then(res => {
console.log('成功回调:', res)
}, 'string')
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
if (this.state === FULFILLED) {
onFulfilled(this.result);
} else if (this.state === REJECTED) {
onRejected(this.result);
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled, onRejected
})
}
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
setTimeout(() => {
// resolve('success')
reject('error')
}, 2000)
})
p.then(res => {
console.log('成功回调:', res)
}, err => {
console.log('失败回调', err)
})
p.then(res => {
console.log('成功回调:', res)
}, err => {
console.log('失败回调', err)
})
queueMicrotask
:新式浏览器均支持,node11开始支持,ie不支持
MutationObserver
:新式浏览器均支持,ie11开始支持
setTimeout
:浏览器支持,node支持
// ------------- 异步任务1 queueMicrotask -------------
// node v11 ie 不支持
// console.log('top')
queueMicrotask(() => {
// ....
})
// console.log('bottom')
// ------------- 异步任务2 MutationObserver -------------
// node 不支持 ie11
console.log('top')
// 创建并返回一个新的观察器,它会在触发指定 DOM 事件时,调用指定的回调函数
const obs = new MutationObserver(() => {
console.log('MutationObserver-run')
})
// 创建div
const divNode = document.createElement('div')
// 监听创建的div ,监听子节点改变
obs.observe(divNode, { childList: true })
// 修改内容触发回调函数
divNode.innerText = 'itheima 666'
console.log('bottom')
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, {childList: true})
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
if (this.state === FULFILLED) {
runAsynctask(() => {
onFulfilled(this.result);
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
onRejected(this.result);
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
onFulfilled(this.result)
})
}, onRejected: () => {
runAsynctask(() => {
onRejected(this.result)
})
}
})
}
}
}
// -----------------测试------------------
console.log('top')
const p = new MyPromise((resolve, reject) => {
resolve('success')
})
p.then(res=> {
console.log(res)
})
console.log('bottom')
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, { childList: true })
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({ onFulfilled }) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({ onRejected }) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
const p2 = new MyPromise((resolve,reject)=> {
if (this.state === FULFILLED) {
runAsynctask(() => {
try {
const x = onFulfilled(this.result);
resolve(x)
} catch (e) {
reject(e)
}
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
onRejected(this.result);
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
onFulfilled(this.result)
})
}, onRejected: () => {
runAsynctask(() => {
onRejected(this.result)
})
}
})
}
})
return p2;
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
resolve('1')
})
p.then(res => {
console.log('p1', res)
throw 'throw-error'
return '2'
}).then(res=> {
console.log('p2',res)
},err=> {
console.log('p2',err)
})
</script>
返回了promise对象,在源码中对这个返回的promise对象进行链式调用,这样就能直接在then的里面获取到结果,其实就是源码帮了个忙,不用开发者自己再链式调用。
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, {childList: true})
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
const p2 = new MyPromise((resolve, reject) => {
if (this.state === FULFILLED) {
runAsynctask(() => {
try {
const x = onFulfilled(this.result);
if (x instanceof MyPromise) {
x.then(res => {
resolve(res)
}, err => {
reject(err)
})
} else {
resolve(x);
}
} catch (e) {
reject(e)
}
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
onRejected(this.result);
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
onFulfilled(this.result)
})
}, onRejected: () => {
runAsynctask(() => {
onRejected(this.result)
})
}
})
}
})
return p2;
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
resolve('1')
})
p.then(res => {
return new MyPromise((resolve, reject) => {
resolve(2)
// reject('error')
})
}).then(res => {
console.log('p2', res)
}, err => {
console.log('p2', err)
})
</script>
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, {childList: true})
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
const p2 = new MyPromise((resolve, reject) => {
if (this.state === FULFILLED) {
runAsynctask(() => {
try {
const x = onFulfilled(this.result);
if (x === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
if (x instanceof MyPromise) {
x.then(res => {
resolve(res)
}, err => {
reject(err)
});
} else {
resolve(x);
}
} catch (e) {
reject(e)
}
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
onRejected(this.result);
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
onFulfilled(this.result)
})
}, onRejected: () => {
runAsynctask(() => {
onRejected(this.result)
})
}
})
}
})
return p2;
}
}
// -----------------测试------------------
// TypeError: Chaining cycle detected for promise #
const p = new MyPromise((resolve, reject) => {
resolve('1')
})
const p2 = p.then(res=> {
return p2;
})
p2.then(res=>{
}, err => {
console.log('err:', err)
}
)
</script>
步骤同处理 fulfilled 状态。
优化:
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, {childList: true})
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
/**
* 处理返回 Promise 和其他值的情况
* @param p2 then 的返回 Promise 结果
* @param x 成功或者失败回调函数的结果
* @param resolve 构造成功的 Promise
* @param reject 构造失败的 Promise
*/
function resolvePromise(p2, x, resolve, reject) {
if (x === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
if (x instanceof MyPromise) {
x.then(res => {
resolve(res)
}, err => {
reject(err)
});
} else {
resolve(x)
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
const p2 = new MyPromise((resolve, reject) => {
if (this.state === FULFILLED) {
runAsynctask(() => {
try {
const x = onFulfilled(this.result);
resolvePromise(p2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
try {
const x = onRejected(this.result);
resolvePromise(p2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
onFulfilled(this.result)
})
}, onRejected: () => {
runAsynctask(() => {
onRejected(this.result)
})
}
})
}
})
return p2;
}
}
// -----------------测试------------------
// TypeError: Chaining cycle detected for promise #
const p = new MyPromise((resolve, reject) => {
reject(1)
})
const p2 = p.then(undefined, err => {
// throw 'err'
// return p2
return 2
// return new MyPromise((resolve, reject)=> {
// resolve('MyPromise-2')
// reject('MyPromise-error')
// })
})
p2.then(res => {
console.log('p2-res:', res)
}, err => {
console.log('p2-err:', err)
}
)
</script>
步骤同处理 rejected 状态。
优化:
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 异步执行任务(底层异步函数放入微任务,最后用宏任务 setTimeout 兜底)
* @param callback
*/
function runAsynctask(callback) {
// 如果浏览器不支持则为 undefined
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, {childList: true})
divNode.innerText = 'heo'
} else {
setTimeout(callback, 0);
}
}
/**
* 处理返回 Promise 和其他值的情况
* @param p2 then 的返回 Promise 结果
* @param x 成功或者失败回调函数的结果
* @param resolve 构造成功的 Promise
* @param reject 构造失败的 Promise
*/
function resolvePromise(p2, x, resolve, reject) {
if (x === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
if (x instanceof MyPromise) {
x.then(res => {
resolve(res)
}, err => {
reject(err)
});
} else {
resolve(x)
}
}
class MyPromise {
/**
* 状态
* @type {string}
*/
state = PENDING
/**
* 原因
* @type {*}
*/
result = undefined
/**
* 保存回调函数的对象数组
* @type {[]}
*/
#handlers = []
constructor(func) {
/**
* 构造成功的 Promise
* @param result
*/
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handlers.forEach(({onFulfilled}) => {
onFulfilled(this.result)
})
}
}
/**
* 构造失败的 Promise
* @param result
*/
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handlers.forEach(({onRejected}) => {
onRejected(this.result)
})
}
}
func(resolve, reject)
}
/**
* then 方法
* @param onFulfilled 成功回调函数
* @param onRejected 失败回调函数
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => {
throw x
}
const p2 = new MyPromise((resolve, reject) => {
if (this.state === FULFILLED) {
runAsynctask(() => {
try {
const x = onFulfilled(this.result);
resolvePromise(p2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (this.state === REJECTED) {
runAsynctask(() => {
try {
const x = onRejected(this.result);
resolvePromise(p2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: () => {
runAsynctask(() => {
try {
const x = onFulfilled(this.result)
resolvePromise(p2,x,resolve,reject)
} catch (e) {
reject(e)
}
})
}, onRejected: () => {
runAsynctask(() => {
try {
const x = onRejected(this.result)
resolvePromise(p2,x,resolve,reject)
} catch (e) {
reject(e)
}
})
}
})
}
})
return p2;
}
}
// -----------------测试------------------
const p = new MyPromise((resolve, reject) => {
setTimeout(()=> {
resolve(1)
},2000)
})
const p2 = p.then(res=> {
// throw 'err'
// return p2
// return 2
return new MyPromise((resolve, reject)=> {
setTimeout(()=> {
// resolve('resolve-2')
reject('reject-2')
},2000)
})
})
p2.then(res => {
console.log('p2-res:', res)
}, err => {
console.log('p2-err:', err)
}
)
</script>