读源码(四)—— js Promise

    技术2026-02-25  8

    写了一些示例还有仿源码自己实现一个简单的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
    Processed: 0.009, SQL: 9