作者:奥兰度
// 异步 Promise + 错误处理 + 链式// new Promise(() => {}).then(() => { return 0}).then((val) => { /* 0 */ })class MyPromise {constructor (executor) {this.status = 'pending'this.value = undefined // resolve valuethis.reason = undefined // reject error// 存放 then 成功和失败的回调,延后运行this.onResolveCallbacks = [] // then(() => {}, () => {})this.onRejectedCallbacks = [] // catch((err) => {})let resolve = (value) => {if (this.status === 'pending') {this.status = 'resolved'if (value instanceof MyPromise) {setTimeout(()=> {const then = value.thenif (typeof then === 'function') {then.call(value, val => {this.value = val}, err => {if (called) returncalled = truethis.reason = err})}})} else {this.value = value}// 收集的回调运行一下this.onResolveCallbacks.forEach(fn => fn())}}let reject = (reason) => {if (this.status === 'pending') {this.status = 'rejected'this.reason = reason// 收集的回调运行一下this.onRejectedCallbacks.forEach(fn => fn())}}try {executor(resolve, reject)} catch (e) {reject(e)}}then(onFullFilled, onRejected) {onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : value => valueonRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }let transPromisetransPromise = new MyPromise((resolve, reject) => {if (this.status === 'resolved') {try {setTimeout(() => {// resolve 后的 then 中 onFullFilled 返回的值是下一个 then 的 onFullFilled 接收的值if (this.value instanceof MyPromise) {this.value = this.value.value}const value = onFullFilled(this.value)resolvePromise(transPromise, value, resolve, reject)})} catch (e) {reject(e)}}if (this.status === 'rejected') {setTimeout(() => {try {const value = onRejected(this.reason)resolvePromise(value)} catch(e) {reject(e)}})}// 收集回调,因为使用了 this 传递,所以值一直存在的if (this.status === 'pending') {this.onResolveCallbacks.push(() => {setTimeout(() => {try {if (this.value instanceof MyPromise) {this.value = this.value.value}const value = onFullFilled(this.value)resolvePromise(transPromise, value, resolve, reject)} catch (e) {reject(e)}})})this.onRejectedCallbacks.push(() => {setTimeout(() => {try {const value = onRejected(this.reason)resolvePromise(value)} catch (e) {reject(e)}})})}})function resolvePromise (transPromise, value, resolve, reject) {if (transPromise === value) {return reject(new TypeError('循环引用'))}let called // 是否调用成功或失败// 看 value 是否是个 Promiseif (value !== null && (typeof value === 'object' || typeof value === 'function')) { // value instanceof MyPromisetry {const then = value.thenif (typeof then === 'function') {then.call(value, val => {if (called) returncalled = trueresolvePromise(transPromise, val, resolve, reject)}, err => {if (called) returncalled = truereject(err)})}} catch (e) {if (called) returncalled = truereject(e)}} else {resolve(value)}}return transPromise}defer () {let dfd = {}dfd.promise = new Promise((resolve, reject) => {dfd.resolve = resolvedfd.reject = reject})return dfd}deferred () {this.defer()}}const myPromiseT = new MyPromise((resolve, reject) => {// setTimeout(() => {resolve('foo');// }, 300);});let promiseA = myPromiseT.then(res => {console.log(res); return res})let promiseB = promiseA.then(res => {console.log(res); return res})let promiseC = promiseB.then(res => {console.log(res); return res})console.log('bar')
作者:
作者:
作者:
