1"use strict"; 2module.exports = 3function(Promise, PromiseArray, apiRejection) { 4var util = require("./util"); 5var RangeError = require("./errors").RangeError; 6var AggregateError = require("./errors").AggregateError; 7var isArray = util.isArray; 8var CANCELLATION = {}; 9 10 11function SomePromiseArray(values) { 12 this.constructor$(values); 13 this._howMany = 0; 14 this._unwrap = false; 15 this._initialized = false; 16} 17util.inherits(SomePromiseArray, PromiseArray); 18 19SomePromiseArray.prototype._init = function () { 20 if (!this._initialized) { 21 return; 22 } 23 if (this._howMany === 0) { 24 this._resolve([]); 25 return; 26 } 27 this._init$(undefined, -5); 28 var isArrayResolved = isArray(this._values); 29 if (!this._isResolved() && 30 isArrayResolved && 31 this._howMany > this._canPossiblyFulfill()) { 32 this._reject(this._getRangeError(this.length())); 33 } 34}; 35 36SomePromiseArray.prototype.init = function () { 37 this._initialized = true; 38 this._init(); 39}; 40 41SomePromiseArray.prototype.setUnwrap = function () { 42 this._unwrap = true; 43}; 44 45SomePromiseArray.prototype.howMany = function () { 46 return this._howMany; 47}; 48 49SomePromiseArray.prototype.setHowMany = function (count) { 50 this._howMany = count; 51}; 52 53SomePromiseArray.prototype._promiseFulfilled = function (value) { 54 this._addFulfilled(value); 55 if (this._fulfilled() === this.howMany()) { 56 this._values.length = this.howMany(); 57 if (this.howMany() === 1 && this._unwrap) { 58 this._resolve(this._values[0]); 59 } else { 60 this._resolve(this._values); 61 } 62 return true; 63 } 64 return false; 65 66}; 67SomePromiseArray.prototype._promiseRejected = function (reason) { 68 this._addRejected(reason); 69 return this._checkOutcome(); 70}; 71 72SomePromiseArray.prototype._promiseCancelled = function () { 73 if (this._values instanceof Promise || this._values == null) { 74 return this._cancel(); 75 } 76 this._addRejected(CANCELLATION); 77 return this._checkOutcome(); 78}; 79 80SomePromiseArray.prototype._checkOutcome = function() { 81 if (this.howMany() > this._canPossiblyFulfill()) { 82 var e = new AggregateError(); 83 for (var i = this.length(); i < this._values.length; ++i) { 84 if (this._values[i] !== CANCELLATION) { 85 e.push(this._values[i]); 86 } 87 } 88 if (e.length > 0) { 89 this._reject(e); 90 } else { 91 this._cancel(); 92 } 93 return true; 94 } 95 return false; 96}; 97 98SomePromiseArray.prototype._fulfilled = function () { 99 return this._totalResolved; 100}; 101 102SomePromiseArray.prototype._rejected = function () { 103 return this._values.length - this.length(); 104}; 105 106SomePromiseArray.prototype._addRejected = function (reason) { 107 this._values.push(reason); 108}; 109 110SomePromiseArray.prototype._addFulfilled = function (value) { 111 this._values[this._totalResolved++] = value; 112}; 113 114SomePromiseArray.prototype._canPossiblyFulfill = function () { 115 return this.length() - this._rejected(); 116}; 117 118SomePromiseArray.prototype._getRangeError = function (count) { 119 var message = "Input array must contain at least " + 120 this._howMany + " items but contains only " + count + " items"; 121 return new RangeError(message); 122}; 123 124SomePromiseArray.prototype._resolveEmptyArray = function () { 125 this._reject(this._getRangeError(0)); 126}; 127 128function some(promises, howMany) { 129 if ((howMany | 0) !== howMany || howMany < 0) { 130 return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); 131 } 132 var ret = new SomePromiseArray(promises); 133 var promise = ret.promise(); 134 ret.setHowMany(howMany); 135 ret.init(); 136 return promise; 137} 138 139Promise.some = function (promises, howMany) { 140 return some(promises, howMany); 141}; 142 143Promise.prototype.some = function (howMany) { 144 return some(this, howMany); 145}; 146 147Promise._SomePromiseArray = SomePromiseArray; 148}; 149