149 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "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;
 | |
| };
 |