[英]Asynchronous Typescript/JavaScript and Dependency Injection
I am fairly new to Typescript/JavaScript. 我对Typescript / JavaScript很陌生。 So this probably a noob question: 所以这可能是一个菜鸟问题:
I have a Typescript class, lets call it serviceActions
. 我有一个Typescript类,可以称之为serviceActions
。
In the constructor
of that class I make a connection to a Web API service via BreezeJS. 在该类的constructor
中,我通过BreezeJS连接到Web API服务。 I also get the metadata for service ( fetchMetadata
). 我还获得了服务的元数据( fetchMetadata
)。
However, the fetchMetadata
call returns a promise. 但是, fetchMetadata
调用返回一个fetchMetadata
。 So the constructor
returns before it is done. 因此, constructor
将在完成之前返回。
Now this serviceActions
class is injected (via Aurelia) into another class: 现在,这个serviceActions
类被注入(通过Aurelia)到另一个类中:
@autoinject
export class BoxVm {
constructor(serviceActions: serviceActions) {
this.box = this.serviceActions.createNewBox();
}
So I never really get to await anything. 所以我从来没有真正等待过。 So when the createNewBox
is called, the fetchMetadata
call is not done, and the call errors out. 因此,当调用createNewBox
时, fetchMetadata
调用未完成,并且调用出错。
Now I could put in an initialize
method on my ServiceActions
class. 现在,我可以在ServiceActions
类上放置一个initialize
方法。 But then I have to wrap everything I do in my BoxVM in the promise for that. 但是然后我必须将我所做的一切都包装在BoxVM中,以实现这一目标。 All calls to get data, save data create any entity would have to be done in a call to initalize.then
. 所有获取数据,保存数据的调用都将创建任何实体,都必须在initalize.then
调用中完成。
Is there another way? 还有另一种方法吗? Am I missing the point? 我错过了重点吗? Or is this the way that Typescript/JavaScript is done? 还是用Typescript / JavaScript完成的方式?
I think this is more a question of how your framework works with dependency injection. 我认为这更多是关于您的框架如何与依赖项注入一起工作的问题。 Syringe lets you inject a "lazy" dependency, which you have to call .get().then(callback)
on in order to use that dependency. 注射器可让您注入“惰性”依赖项,您必须先调用.get().then(callback)
才能使用该依赖项。
In general, though, yes: any time you need to use something that gets produced by an asynchronous operation, you're going to need to access it through the promise interface. 但总的来说,是的:每当您需要使用异步操作生成的内容时,就需要通过promise接口访问它。 This will become syntactically easier once TypeScript adds better async/await
support, but you can't just assume you've got access to a resource for injection if that resource is produced via an asynchronous operation. 一旦TypeScript添加了更好的async/await
支持,这在语法上将变得更加容易,但是如果该资源是通过异步操作生成的,则不能仅仅假设您可以访问该资源以进行注入。
The problem is that ServiceActions
is waiting for a promise to be fulfilled before it can be usable. 问题在于ServiceActions
在等待兑现可用之前正在等待兑现承诺。 There are several solutions: 有几种解决方案:
await
the results of a promise. 等待ES7,这让我们await
承诺的结果。 Your createNewBox
function will wait patiently for the promise to finish before returning. 您的createNewBox
函数将耐心等待诺言完成,然后再返回。 This is the cleanest solution. 这是最干净的解决方案。 fetchMetadata
into the constructor (possibly making the call before running your DI framework initialization). 找出将fetchMetadata
的结果fetchMetadata
到构造函数中的方法(可能在运行DI框架初始化之前进行调用)。 This avoids the problem. 这避免了该问题。 initialize().then
, though it seems mildly error-prone (someone might forget to wrap code in init). 使用initialize().then
执行您建议的操作,尽管它似乎容易出错(某些人可能会忘记将代码包装在init中)。 onInit
function in ServiceActions
that takes a callback - it's a mildly refactored version of what you're suggesting. 在ServiceActions
中创建一个onInit
函数-它是您所建议内容的轻度重构版本。 createNewBox
return a promise to hand over a new Box
once ServiceActions
is done waiting for the fetchMetadata
promise. 一旦ServiceActions
完成等待fetchMetadata
承诺, fetchMetadata
createNewBox
返回一个承诺以移交新Box
。 This might pollute everything with many promises. 这可能会污染许多承诺的一切。 I would try for option 2, especially since you seem to need to call this only once. 我会尝试选项2,尤其是因为您似乎只需要调用一次即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.