7 喜欢

实现一个简单的Promise

admin
admin
2020-08-07 00:47:51 阅读 252
// author: xiang // date: 2020-08-07 var PENDING = 'pending' var FULFILLED = 'fulfilled' var REJECTED = 'rejected' var NOOP = function(){} var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout; function resolve(value) { if (this._state === PENDING) { this._state = FULFILLED this._data = value asyncCall.call(this) } } function reject(reason) { if (this._state === PENDING) { this._state = REJECTED this._data = reason asyncCall.call(this) } } function invokeResolver(resolver) { try { resolver(resolve.bind(this), reject.bind(this)) } catch (e) { reject.call(this, e) } } function invokeCallback(subscriber) { var owner = subscriber.owner var state = owner._state var value = owner._data var callback = subscriber[state] var promise = subscriber.then try { value = callback(value) resolve.call(promise, value) } catch(e) { reject.call(promise, e) } } function asyncCall() { asyncSetTimer(asyncFlush.bind(this), 0); } function asyncFlush() { var callbacks = this._then for (let i = 0, len = callbacks.length; i < len; i++) { invokeCallback(callbacks[i]) } } function promise(resolver) { if (!(this instanceof promise)) { throw new TypeError("Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.") } if (typeof resolver !== "function") { throw new TypeError("promise resolver is not function") } this._then = [] invokeResolver.call(this, resolver) } promise.prototype = { constructor: promise, _then: null, _state: PENDING, _data: null, then(onFulfillment, onRejection) { var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection } if (this._state === FULFILLED || this._state === REJECTED) asyncFlush.call(this) this._then.push(subscriber) return subscriber.then }, catch(onRejection) { return this.then(null, onRejection) } } promise.all = function(promises) { if (!Array.isArray(promises)) { throw new TypeError("promises is not iterable") } return new this(function(resolve, reject) { var results = [] var remaining = 0 var prom = null function resolver(index) { remaining++ return function(value) { results[index] = value if (!--remaining) resolve(results) } } for (let i = 0, len = promises.length; i < len; i++) { prom = promises[i] if (prom && typeof prom.then === "function") { prom.then(resolver(i), reject) } else { results[i] = prom } } if (!remaining) resolve(results) }) } promise.race = function(promises) { if (!Array.isArray(promises)) { throw new TypeError("promises is not iterable") } return new this(function(resolve, reject) { var prom = null for (let i = 0, len = promises.length; i < len; i++) { prom = promises[i] if (prom && typeof prom.then === "function") { prom.then(resolve, reject) } else { resolve(prom) } } }) } promise.resolve = function(value) { return new this(function(resolve) { resolve(value) }) } promise.reject = function(reason) { return new this(function(resolve, reject) { reject(reason) }) }

关于作者
admin
admin
admin@ifront.net
 获得点赞 37
 文章阅读量 8888