You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					149 lines
				
				3.9 KiB
			
		
		
			
		
	
	
					149 lines
				
				3.9 KiB
			| 
											3 years ago
										 | "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; | ||
|  | }; |