ember-source
Version:
A JavaScript framework for creating ambitious web applications
141 lines (122 loc) • 3.9 kB
JavaScript
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 };