| "use strict"; |
| module.exports = |
| function(Promise, PromiseArray, apiRejection) { |
| var util = require("./util"); |
| var RangeError = require("./errors").RangeError; |
| var AggregateError = require("./errors").AggregateError; |
| var isArray = util.isArray; |
| var CANCELLATION = {}; |
| |
| |
| function SomePromiseArray(values) { |
| this.constructor$(values); |
| this._howMany = 0; |
| this._unwrap = false; |
| this._initialized = false; |
| } |
| util.inherits(SomePromiseArray, PromiseArray); |
| |
| SomePromiseArray.prototype._init = function () { |
| if (!this._initialized) { |
| return; |
| } |
| if (this._howMany === 0) { |
| this._resolve([]); |
| return; |
| } |
| this._init$(undefined, -5); |
| var isArrayResolved = isArray(this._values); |
| if (!this._isResolved() && |
| isArrayResolved && |
| this._howMany > this._canPossiblyFulfill()) { |
| this._reject(this._getRangeError(this.length())); |
| } |
| }; |
| |
| SomePromiseArray.prototype.init = function () { |
| this._initialized = true; |
| this._init(); |
| }; |
| |
| SomePromiseArray.prototype.setUnwrap = function () { |
| this._unwrap = true; |
| }; |
| |
| SomePromiseArray.prototype.howMany = function () { |
| return this._howMany; |
| }; |
| |
| SomePromiseArray.prototype.setHowMany = function (count) { |
| this._howMany = count; |
| }; |
| |
| SomePromiseArray.prototype._promiseFulfilled = function (value) { |
| this._addFulfilled(value); |
| if (this._fulfilled() === this.howMany()) { |
| this._values.length = this.howMany(); |
| if (this.howMany() === 1 && this._unwrap) { |
| this._resolve(this._values[0]); |
| } else { |
| this._resolve(this._values); |
| } |
| return true; |
| } |
| return false; |
| |
| }; |
| SomePromiseArray.prototype._promiseRejected = function (reason) { |
| this._addRejected(reason); |
| return this._checkOutcome(); |
| }; |
| |
| SomePromiseArray.prototype._promiseCancelled = function () { |
| if (this._values instanceof Promise || this._values == null) { |
| return this._cancel(); |
| } |
| this._addRejected(CANCELLATION); |
| return this._checkOutcome(); |
| }; |
| |
| SomePromiseArray.prototype._checkOutcome = function() { |
| if (this.howMany() > this._canPossiblyFulfill()) { |
| var e = new AggregateError(); |
| for (var i = this.length(); i < this._values.length; ++i) { |
| if (this._values[i] !== CANCELLATION) { |
| e.push(this._values[i]); |
| } |
| } |
| if (e.length > 0) { |
| this._reject(e); |
| } else { |
| this._cancel(); |
| } |
| return true; |
| } |
| return false; |
| }; |
| |
| SomePromiseArray.prototype._fulfilled = function () { |
| return this._totalResolved; |
| }; |
| |
| SomePromiseArray.prototype._rejected = function () { |
| return this._values.length - this.length(); |
| }; |
| |
| SomePromiseArray.prototype._addRejected = function (reason) { |
| this._values.push(reason); |
| }; |
| |
| SomePromiseArray.prototype._addFulfilled = function (value) { |
| this._values[this._totalResolved++] = value; |
| }; |
| |
| SomePromiseArray.prototype._canPossiblyFulfill = function () { |
| return this.length() - this._rejected(); |
| }; |
| |
| SomePromiseArray.prototype._getRangeError = function (count) { |
| var message = "Input array must contain at least " + |
| this._howMany + " items but contains only " + count + " items"; |
| return new RangeError(message); |
| }; |
| |
| SomePromiseArray.prototype._resolveEmptyArray = function () { |
| this._reject(this._getRangeError(0)); |
| }; |
| |
| function some(promises, howMany) { |
| if ((howMany | 0) !== howMany || howMany < 0) { |
| return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); |
| } |
| var ret = new SomePromiseArray(promises); |
| var promise = ret.promise(); |
| ret.setHowMany(howMany); |
| ret.init(); |
| return promise; |
| } |
| |
| Promise.some = function (promises, howMany) { |
| return some(promises, howMany); |
| }; |
| |
| Promise.prototype.some = function (howMany) { |
| return some(this, howMany); |
| }; |
| |
| Promise._SomePromiseArray = SomePromiseArray; |
| }; |