Class decorators and async process
Gray Zhang
otakustay at icloud.com
Sun May 24 03:38:26 UTC 2015
Sorry for some confusing descriptions, IoC means Inversion of Control here, I’d like to put all code together here:
// A simple implement of IoC
ioc.getComponent = (name) {
return new Promise((resolve) => {
let iocConfig = parseConfig(name);
let moduleId = iocConfig.module;
require([moduleId], function (ModuleClass) {
let instance = new ModuleClass();
injectProperties(instance, iocConfig);
resolve(instance);
});
});
}
let inject = (name) => {
return (target, key, descriptor) => {
// target = hero
// key = 'weapon'
// Use initializer to get the property value
descriptor.initializer = () => {
return ioc.getComponent(name);
};
};
};
class Hero {
// We need a knife from ioc as this hero's weapon
@inject('knife')
weapon = null;
hit(enemy) {
// Problem here
enemy.heath -= this.weapon.power - enemy.defense;
}
}
The problem is, as I know, when a decorator implements the descriptor.initializer the property value should be the return value of this initializer, however the initializer should be sync which directly returns the value but not a promise or a async function, we can’t await for a descriptor.initializer
In this case, in my hit method, the this.weapon is a Promise but not a knife instance, Promise does not have e a power property so hit method fails, I may correct the code:
hit(enemy) {
return this.weapon.then((weapon) => {
emeny.heath -= weapon.power - enemy.defense;
});
}
It’s OK, I just wait for this.weapon to resolve, but then my hit method becomes async, and everything based on @inject property should be async, which is not actually what I want.
Is the decorator idea based on extended property descriptors actually being used, e.g., with Babel? Sorry if I missed it.
Decorator is now supported with Babel 5.0 and I was trying this these days, expecting it could be integrated with our IoC framework, just as how Spring works in Java.
Best regards
Gray Zhang
在 2015年5月24日 上午2:54:43, Eich Brendan (brendan at mozilla.org) 写到:
Gray Zhang wrote:
>
> Hi all:
>
> I’m wondering if there is any way to combine a class decorator and an
> async process together? A common case would be a generic IoC
> implementation:
>
First, too many undefined terms and made-up syntax extensions just makes
for confusion. Can you define "async process"? To optimize I'll assume
you mean async function, a function returning a promise.
> Since in JavaScript IoC
>
IoC = Inversion of Control -- just checking!
> we load runtime modules async by a config file, the interface may be:
>
> |{Promise} ioc.getComponent({string} componentName)
> |
Nicer to use reserved type annotation syntax:
| ioc.getComponent(componentName: string): Promise|
I hope that's what {T} D means!
> which resolves the returned Promise giving required instance of
> |componentName|, and this is a method that cannot be sync since we
> need a config file to map |componentName| to its implementing module
> and load the module lazily (for performance reason)
>
> This is an async process so if we add a decorator to a class property:
>
> |function inject(name) {
> return (target, key, descriptor) {|
Missing `function` after `return`?
> |
> // Note this returns a promise, not the actual property value
> descriptor.initializer = () => ioc.getComponent(name);
> }
> }
>
> class Hero {
> @inject('knife')
> weapon = null|
So the decorator calls the anonymous function with key='knife',
target=instance-of-Hero, and descriptor the property descriptor,
extended with .initializer?
BTW the idea of using property descriptors for decorators got push-back
and an alternative suggestion at the March TC39 meeting.
> |
>
> hit(enemy) {
> enemy.heath -= (this.weapon.power - enemy.defense);
> }
> }
> |
>
> This code may not work, but nobody likes there injected properties to
> be all async getters and all code logics become unnecessarily complex
> by introducing so many async processes
>
Have you read about `await` and `async` in ES7?
> How so we think of such common case, should I just make the
> |ioc.getComponent| sync without considerations to performance,
>
"performance" is not really accurate: responsiveness and even deadlock
avoidance come to mind. If you're talking about a browser API, then you
can't do sync loading (apart from bad old sync XHR), so async/await is
the way to go.
> or should I give up the decorator solution?
>
Is the decorator idea based on extended property descriptors actually
being used, e.g., with Babel? Sorry if I missed it.
/be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150524/dbfd82ba/attachment-0001.html>
More information about the es-discuss
mailing list