some.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. "use strict";
  2. module.exports =
  3. function(Promise, PromiseArray, apiRejection) {
  4. var util = require("./util.js");
  5. var RangeError = require("./errors.js").RangeError;
  6. var AggregateError = require("./errors.js").AggregateError;
  7. var isArray = util.isArray;
  8. function SomePromiseArray(values) {
  9. this.constructor$(values);
  10. this._howMany = 0;
  11. this._unwrap = false;
  12. this._initialized = false;
  13. }
  14. util.inherits(SomePromiseArray, PromiseArray);
  15. SomePromiseArray.prototype._init = function () {
  16. if (!this._initialized) {
  17. return;
  18. }
  19. if (this._howMany === 0) {
  20. this._resolve([]);
  21. return;
  22. }
  23. this._init$(undefined, -5);
  24. var isArrayResolved = isArray(this._values);
  25. if (!this._isResolved() &&
  26. isArrayResolved &&
  27. this._howMany > this._canPossiblyFulfill()) {
  28. this._reject(this._getRangeError(this.length()));
  29. }
  30. };
  31. SomePromiseArray.prototype.init = function () {
  32. this._initialized = true;
  33. this._init();
  34. };
  35. SomePromiseArray.prototype.setUnwrap = function () {
  36. this._unwrap = true;
  37. };
  38. SomePromiseArray.prototype.howMany = function () {
  39. return this._howMany;
  40. };
  41. SomePromiseArray.prototype.setHowMany = function (count) {
  42. this._howMany = count;
  43. };
  44. SomePromiseArray.prototype._promiseFulfilled = function (value) {
  45. this._addFulfilled(value);
  46. if (this._fulfilled() === this.howMany()) {
  47. this._values.length = this.howMany();
  48. if (this.howMany() === 1 && this._unwrap) {
  49. this._resolve(this._values[0]);
  50. } else {
  51. this._resolve(this._values);
  52. }
  53. }
  54. };
  55. SomePromiseArray.prototype._promiseRejected = function (reason) {
  56. this._addRejected(reason);
  57. if (this.howMany() > this._canPossiblyFulfill()) {
  58. var e = new AggregateError();
  59. for (var i = this.length(); i < this._values.length; ++i) {
  60. e.push(this._values[i]);
  61. }
  62. this._reject(e);
  63. }
  64. };
  65. SomePromiseArray.prototype._fulfilled = function () {
  66. return this._totalResolved;
  67. };
  68. SomePromiseArray.prototype._rejected = function () {
  69. return this._values.length - this.length();
  70. };
  71. SomePromiseArray.prototype._addRejected = function (reason) {
  72. this._values.push(reason);
  73. };
  74. SomePromiseArray.prototype._addFulfilled = function (value) {
  75. this._values[this._totalResolved++] = value;
  76. };
  77. SomePromiseArray.prototype._canPossiblyFulfill = function () {
  78. return this.length() - this._rejected();
  79. };
  80. SomePromiseArray.prototype._getRangeError = function (count) {
  81. var message = "Input array must contain at least " +
  82. this._howMany + " items but contains only " + count + " items";
  83. return new RangeError(message);
  84. };
  85. SomePromiseArray.prototype._resolveEmptyArray = function () {
  86. this._reject(this._getRangeError(0));
  87. };
  88. function some(promises, howMany) {
  89. if ((howMany | 0) !== howMany || howMany < 0) {
  90. return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/1wAmHx\u000a");
  91. }
  92. var ret = new SomePromiseArray(promises);
  93. var promise = ret.promise();
  94. ret.setHowMany(howMany);
  95. ret.init();
  96. return promise;
  97. }
  98. Promise.some = function (promises, howMany) {
  99. return some(promises, howMany);
  100. };
  101. Promise.prototype.some = function (howMany) {
  102. return some(this, howMany);
  103. };
  104. Promise._SomePromiseArray = SomePromiseArray;
  105. };