static all()

in src/core/Deferred.js [229:327]


  static all(iterable, onResolve, onReject, onCancel) {
    if (iterable == null || typeof iterable[Symbol.iterator] !== 'function') {
      let e = `Cannot execute Deferred.all. First argument must be iterable.`;

      if (typeof onReject === 'function') {
        e = onReject(e);
      }

      return Deferred.reject(e);
    }

    const array = [...iterable];
    const deferred = array.filter(item => item instanceof Deferred);

    const result = new Deferred(
      undefined,
      resolveValue => {
        deferred.forEach(item => {
          item.resolve(resolveValue);
        });
        deferred.length = 0;

        if (typeof onResolve === 'function') {
          return onResolve(resolveValue);
        } else {
          return resolveValue;
        }
      },
      error => {
        deferred.forEach(item => {
          item.reject(error);
        });
        deferred.length = 0;

        if (typeof onReject === 'function') {
          return onReject(error);
        } else {
          return error;
        }
      },
      cancelValue => {
        deferred.forEach(item => {
          item.cancel(cancelValue);
        });
        deferred.length = 0;

        if (typeof onCancel === 'function') {
          return onCancel(cancelValue);
        } else {
          return cancelValue;
        }
      }
    );

    const numItems = array.length;
    const itemTracker = {
      failed: false,
      numResolved: 0,
      resolutions: []
    }

    array.forEach((item, index) => {
      if (itemTracker.failed) {
        return;
      } else if (!(item instanceof Promise)) {
        itemTracker.resolutions[index] = item;
        itemTracker.numResolved += 1;

        if (itemTracker.numResolved === numItems) {
          result.resolve(itemTracker.resolutions);
        }
        return;
      }

      item.then(
        value => {
          if (!itemTracker.failed && !item.canceled) {
            itemTracker.resolutions[index] = value;
            itemTracker.numResolved += 1;

            if (itemTracker.numResolved === numItems) {
              result.resolve(itemTracker.resolutions);
            }
          } else if (!itemTracker.failed) {
            itemTracker.failed = true;
            result.cancel(value);
          }
        },
        error => {
          if (!itemTracker.failed) {
            itemTracker.failed = true;
            result.reject(error);
          }
        }
      );
    });

    return result;
  }