addon/mixins/promise-resolver.js
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
}
}
});