前端开发Kingcean 2020-05-30
export default class Promise2 { state=‘pending‘ callbacks = [] resolve(result) { this.excute(‘fulfilled‘, result, 0) } reject(reason) { this.excute(‘rejected‘, reason, 1) } excute(state, data, i) { if(this.state !== ‘pending‘) return this.state = state nextTick(() => { this.callbacks.forEach(el => { if(typeof el[i] === ‘function‘) { let x try { x = el[i].call(undefined, data) } catch (error) { el[2].reject(error) } el[2].resolveWith(x) } }) }) } constructor(fn) { fn(this.resolve.bind(this), this.reject.bind(this)) } then(succeed?, failed?) { const arr = [] if(typeof succeed === ‘function‘) { arr[0] = succeed } if(typeof failed === ‘function‘) { arr[1] = failed } arr[2] = new Promise2(() => {}) this.callbacks.push(arr) return arr[2] } resolveWithThenable(x) { try { x.then( y => { this.resolveWith(y); }, r => { this.reject(r); } ); } catch (e) { this.reject(e); } } resolveWith(x) { if (this === x) this.reject(new TypeError()) else if (x instanceof Promise2) { x.then(res => { this.resolve(res) }, err => { this.reject(err) }) } else if (x instanceof Object) { // if a thenable let then try { then = x.then } catch(e) { this.reject(e) } if (then instanceof Function) { this.resolveWithThenable(x) } else { this.resolve(x) } } else { this.resolve(x) } } } function nextTick(fn) { if(process !== undefined && typeof process.nextTick === ‘function‘) return process.nextTick(fn) else { var counter = 1 var observer = new MutationObserver(fn) var textNode = document.createTextNode(String(counter)) observer.observe(textNode, { characterData: true }) counter = counter+1 textNode.data = String(counter) } }