unchartedcode/ember-promise-tools

View on GitHub
addon/mixins/promise-resolver.js

Summary

Maintainability
A
1 hr
Test Coverage
import { Promise } from 'rsvp';
import Mixin from '@ember/object/mixin';
import isPromise from 'ember-promise-tools/utils/is-promise';
import isFulfilled from 'ember-promise-tools/utils/is-fulfilled';
import getPromiseContent from 'ember-promise-tools/utils/get-promise-content';

// Code referenced from https://github.com/fivetanley/ember-promise-helpers
export default Mixin.create({
  resolvePromise(maybePromise, immediateResolve, delayedResolve, catchResolve) {
    if (!isPromise(maybePromise)) {
      this.clearPromise();
      return immediateResolve.call(this, maybePromise);
    }
    // If we've already fulfilled, just return to avoid returning null
    // Probably could tie into SetValue, something to think about later
    if (isFulfilled(maybePromise)) {
      this.clearPromise();
      return immediateResolve.call(this, getPromiseContent(maybePromise));
    }

    // If the type wasn't a PromiseProxy or RSVP, check if we resolved for .then
    if (maybePromise === this._currentPromise) {
      if (this._promiseWasSettled) {
        return immediateResolve.call(this, this._promiseValue);
      }
      return null; // Return we don't need to check the latest again
    }

    this.ensureLatestPromise(maybePromise, (promise) => {
      promise.then((value) => {
        if (maybePromise === this._currentPromise) {
          this._promiseWasSettled = true;
          this._promiseValue = value;
          // This will recompue the value and fire the _wasSettled check above
          return (delayedResolve || immediateResolve).call(this, value);
        }
      }).catch((error) => {
        if (catchResolve != null) {
          return catchResolve.call(this, error);
        } else {
          this.log_error('Promise died in promise-resolver and no catchResolve method was passed in.');
          this.log_error(error);
        }
      });
    });
    return null;
  },

  ensureLatestPromise(promise, callback) {
    this.clearPromise(promise);
    callback.call(this, Promise.resolve(promise));
  },

  clearPromise(promise = null) {
    // It's a new promise, reset
    this._promiseWasSettled = false;
    this._currentPromise = promise;
  },

  log_error(message) {
    if (window.console && window.console.error) {
      window.console.error(message);
    } else {
      // Do nothing, not supported by browser
    }
  }
});