什么是异步初始化服务
前面有介绍什么是服务,服务是指包含数据和方法的对象。
关键在于怎么初始化服务的数据。一般来说简单的服务就是代码在定义服务时就写死的默认数据。此时不会涉及到异步初始化服务。
当我们初始化服务的数据需要从服务器端获取时,就需要通过接口异步获取数据后才能完成数据的初始化。
示例 1
ts
class A {
public id = 1;
public name = 'A';
}
这里的 A 是一个服务,而且可以明确看出来这个服务是不依赖服务器端数据的,所以不需要异步初始化数据。
示例 2
ts
class A {
public id = 1;
public name = 'A';
@PostConstruct()
public init() {
return fetch('api_url').then(res => {
this.id = res.id;
this.name = res.name;
});
}
}
这里通过@PostConstruct
装饰了一个 init 方法。这个 init 方法会在服务实例化之后自动执行,这样就能自动通过接口从服务器端拉取数据,从而完成服务数据的初始化。
示例 3
ts
class B {
public id = 2;
public name = 'B';
@PostConstruct()
public init() {
return fetch('api_url').then(res => {
this.id = res.id;
this.name = res.name;
});
}
}
class A {
public id = 1;
public name = 'A';
@Inject(B)
public b: B;
@PostConstruct(true)
public init() {
this.id = this.b.id + 1;
this.name = this.b.name + 'A';
}
}
这个例子稍微有些复杂。其中 B 服务依赖后端接口返回的数据用户初始化服务。同时 A 服务的 init 方法又是依赖 B 服务的 id 和 name 属性的。 这里显然需要控制代码的执行顺序。如果两个 init 方法同时执行,则 A.init 执行时,B 服务还没有获取到服务器端数据,此时 A 服务访问的就是 B 服务的默认数据,显然这不是我们期望的逻辑。 所以这里使用了@PostConstruct(true)
,这里的true
用于控制等待 A 的所有注入的属性全部完成初始化之后再去执行 A 服务自己的 init 方法。这样 A.init 方法中就能访问到真实的 B 服务的数据了。
示例 4
ts
class C {
public id = 3;
public name = 'C';
@PostConstruct()
public init() {
return fetch('api_url_C').then(res => {
this.id = res.id;
this.name = res.name;
});
}
}
class B {
public id = 2;
public name = 'B';
@PostConstruct()
public init() {
return fetch('api_url_B').then(res => {
this.id = res.id;
this.name = res.name;
});
}
}
class A {
public id = 1;
public name = 'A';
@Inject(B)
public b: B;
@Inject(C)
public c: C;
@PostConstruct(true)
public init() {
this.id = this.b.id + this.c.id + 1;
this.name = this.b.name + this.c.name + 'A';
}
}
这个例子展示了 A 服务同时依赖 B 和 C 两个服务,此时 A 服务也会等待 B 服务和 C 服务都完成初始化之后,才会执行 A.init 方法。
示例 5
ts
class C {
public id = 3;
public name = 'C';
@PostConstruct()
public init() {
return fetch('api_url_C').then(res => {
this.id = res.id;
this.name = res.name;
});
}
}
class B {
public id = 2;
public name = 'B';
@Inject(C)
public c: C;
@PostConstruct(true)
public init() {
this.id = this.c.id + 2;
this.name = this.c.name + 'B';
}
}
class A {
public id = 1;
public name = 'A';
@Inject(B)
public b: B;
@PostConstruct(true)
public init() {
this.id = this.b.id + 1;
this.name = this.b.name + 'A';
}
}
这个例子展示了 A 服务依赖 B 服务,B 服务又是依赖 C 服务。首先 B 服务会等待 C 服务完成初始化,才会执行 B.init 方法。等到 B 服务完成初始化,才会执行 A.init 方法,最终完成 A 服务的初始化。