UNPKG

ember-source

Version:

A JavaScript framework for creating ambitious web applications

141 lines (122 loc) 3.9 kB
import './index.js'; import Mixin from './mixin.js'; import { c as computed, g as get } from '../../shared-chunks/cache-DORQczuy.js'; import '../-internals/meta/lib/meta.js'; import '../debug/index.js'; import '../../@glimmer/validator/index.js'; import '../../shared-chunks/mandatory-setter-BiXq-dpN.js'; import '@embroider/macros'; import '../../@glimmer/destroyable/index.js'; import '../../@glimmer/manager/index.js'; import { s as setProperties } from '../../shared-chunks/set_properties-BQFOCF2x.js'; import '../../shared-chunks/env-mInZ1DuF.js'; /** @module @ember/object/promise-proxy-mixin */ function tap(proxy, promise) { setProperties(proxy, { isFulfilled: false, isRejected: false }); return promise.then(value => { if (!proxy.isDestroyed && !proxy.isDestroying) { setProperties(proxy, { content: value, isFulfilled: true }); } return value; }, reason => { if (!proxy.isDestroyed && !proxy.isDestroying) { setProperties(proxy, { reason, isRejected: true }); } throw reason; }, 'Ember: PromiseProxy'); } /** A low level mixin making ObjectProxy promise-aware. ```javascript import { resolve } from 'rsvp'; import $ from 'jquery'; import ObjectProxy from '@ember/object/proxy'; import PromiseProxyMixin from '@ember/object/promise-proxy-mixin'; let ObjectPromiseProxy = ObjectProxy.extend(PromiseProxyMixin); let proxy = ObjectPromiseProxy.create({ promise: resolve($.getJSON('/some/remote/data.json')) }); proxy.then(function(json){ // the json }, function(reason) { // the reason why you have no json }); ``` the proxy has bindable attributes which track the promises life cycle ```javascript proxy.get('isPending') //=> true proxy.get('isSettled') //=> false proxy.get('isRejected') //=> false proxy.get('isFulfilled') //=> false ``` When the $.getJSON completes, and the promise is fulfilled with json, the life cycle attributes will update accordingly. Note that $.getJSON doesn't return an ECMA specified promise, it is useful to wrap this with an `RSVP.resolve` so that it behaves as a spec compliant promise. ```javascript proxy.get('isPending') //=> false proxy.get('isSettled') //=> true proxy.get('isRejected') //=> false proxy.get('isFulfilled') //=> true ``` As the proxy is an ObjectProxy, and the json now its content, all the json properties will be available directly from the proxy. ```javascript // Assuming the following json: { firstName: 'Stefan', lastName: 'Penner' } // both properties will accessible on the proxy proxy.get('firstName') //=> 'Stefan' proxy.get('lastName') //=> 'Penner' ``` @class PromiseProxyMixin @public */ const PromiseProxyMixin = Mixin.create({ reason: null, isPending: computed('isSettled', function () { return !get(this, 'isSettled'); }).readOnly(), isSettled: computed('isRejected', 'isFulfilled', function () { return get(this, 'isRejected') || get(this, 'isFulfilled'); }).readOnly(), isRejected: false, isFulfilled: false, promise: computed({ get() { throw new Error("PromiseProxy's promise must be set"); }, set(_key, promise) { return tap(this, promise); } }), then: promiseAlias('then'), catch: promiseAlias('catch'), finally: promiseAlias('finally') }); function promiseAlias(name) { return function (...args) { let promise = get(this, 'promise'); // We need this cast because `Parameters` is deferred so that it is not // possible for TS to see it will always produce the right type. However, // since `AnyFn` has a rest type, it is allowed. See discussion on [this // issue](https://github.com/microsoft/TypeScript/issues/47615). return promise[name](...args); }; } export { PromiseProxyMixin as default };