poelstra / ts-promise

TS-Promise - fast, robust, type-safe promises
MIT License
45 stars 5 forks source link

Promise.settle() method #1

Open rogierschouten opened 9 years ago

rogierschouten commented 9 years ago

The Promise.all() method does not wait for all promises to end in case one rejects. In order to implement one that does, I would need a .settle() method. So please provide either a .settle() method or a all2void() method along these lines:

/**
 * Same as all() defined above but returns a void promise if everything goes well.
 * Implementation is repeated for performance reasons.
 */
export function all2void<T>(promises: Promise<T>[]): Promise<void> {
    // optimizations
    if (promises.length === 0) {
        return Promise.resolve();
    }
    if (promises.length === 1) {
        var inspection = promises[0];
        return promises[0]
            .return()
            .catch((error: Error): Promise<void> => {
                return Promise.reject(new xerror.MultiPromiseError([inspection]));
            });
    }
    return Promise.settle(promises)
        .then((results: Promise.Inspection<T>[]): Promise<void> => {
            var allOk: boolean = true;
            for (var i = 0; i < results.length; ++i) {
                if (results[i].isRejected()) {
                    allOk = false;
                    break;
                }
            }
            if (allOk) {
                return Promise.resolve();
            } else {
                return Promise.reject(new xerror.MultiPromiseError(results));
            }
        });
}
rogierschouten commented 9 years ago

Actually, here is a ts-promise implementation of all2void:

export function tsAll2void<T>(promises: tsPromise.Promise<T>[]): tsPromise.Promise<void> {
    if (promises.length === 0) {
        return tsPromise.Promise.resolve();
    }
    if (promises.length === 1) {
        return promises[0]
            .then((): void => {
                // nothing
            });
    }
    var deferredResult = tsPromise.Promise.defer();
    var remaining = promises.length;
    var errors: Error[] = [];
    for (var i = 0; i < promises.length; ++i) {
        follow(promises[i]);
    }

    function follow(promise: tsPromise.Promise<T>): void {
        promise
            .done(checkDone, (error: Error): void => {
                errors.push(error);
                checkDone();
            });
    }

    function checkDone(): void {
        remaining--;
        if (remaining === 0) {
            if (errors.length > 0) {
                deferredResult.reject(new xerror.AggregateError("All2VoidError", errors));
            } else {
                deferredResult.resolve();
            }
        }
    }

    return deferredResult.promise;
}
poelstra commented 9 years ago

Thanks! Will look at this later.

On 2 juli 2015 15:39:04 GMT+07:00, Rogier Schouten notifications@github.com wrote:

Actually, here is a ts-promise implementation of all2void:

export function tsAll2void<T>(promises: tsPromise.Promise<T>[]):
tsPromise.Promise<void> {
  if (promises.length === 0) {
      return tsPromise.Promise.resolve();
  }
  if (promises.length === 1) {
      return promises[0]
          .then((): void => {
              // nothing
          });
  }
  var deferredResult = tsPromise.Promise.defer();
  var remaining = promises.length;
  var errors: Error[] = [];
  for (var i = 0; i < promises.length; ++i) {
      follow(promises[i]);
  }

  function follow(promise: tsPromise.Promise<T>): void {
      promise
          .done(checkDone, (error: Error): void => {
              errors.push(error);
              checkDone();
          });
  }

  function checkDone(): void {
      remaining--;
      if (remaining === 0) {
          if (errors.length > 0) {
              deferredResult.reject(new xerror.AggregateError("All2VoidError",
errors));
          } else {
              deferredResult.resolve();
          }
      }
  }

  return deferredResult.promise;
}

Reply to this email directly or view it on GitHub: https://github.com/poelstra/ts-promise/issues/1#issuecomment-117958944