【发布时间】:2022-01-24 06:31:04
【问题描述】:
我正在努力编写等待相关服务准备数据的编码。我现在有一个大脑锁定,我没有得到我期望的行为。 我的期望是 home.ts 页面依赖于 B 服务,而 B 服务又依赖于首先完成的 A 服务。此外,我不想让 home.ts 页面知道 A 服务(理想情况下)。
我在 stackblitz 中进行了以下简化尝试,第一次使用每个服务公开的 Ready_P 承诺。但是,我现在意识到,通常取决于注入机制,它是未定义的,因此 this.BService.Ready_P.then().. 行在 home.ts 的构造函数中失败。
有什么更好/正确的处理方式?
// home.ts
import { CService } from './CService'; // 20220122
import { BService } from './BService'; // 20220122
//
@Component({
selector: 'home',
templateUrl: 'home.html',
styleUrls: ['./home.scss'],
// encapsulation: ViewEncapsulation.None
})
export class home {
constructor(
//
//
public CService: CService,
public BService: BService
) {
this.Init();
}
//
async Init() {
await this.CService.Load();
console.log('CService Ready from home');
await this.BService.Load();
console.log('BService Ready from home');
}
}
// C.ts
import { BService } from './BService'; // 20220122
/** # CService Depends on BService being data ready
* - 20220122 */
@Injectable()
export class CService {
// 20220122
constructor(
//
public BService: BService
) {
// this.BService.Load().then(() => {
// console.log('BService Ready from C');
// this.Load();
// });
}
//
//
Ready_P: Promise<boolean>;
//
async Load() {
await this.BService.Load()
// Do work
// if (this.Ready_P) return this.Ready_P; // to avoid repeated execution.
return (this.Ready_P = new Promise((resolve) => {
setTimeout(() => {
console.log('C Resolves');
resolve(true);
}, 1000);
}));
}
}
// B.ts
import { AService } from './AService'; // 20220122
/** # BService Depends on AService being data ready
* - 20220122 */
@Injectable()
export class BService {
// 20220122
constructor(
//
public AService: AService
) {
}
//
//
Ready_P: Promise<boolean>;
//
async Load() {
await this.AService.Load()
// Do work
// if (this.Ready_P) return this.Ready_P // to avoid repeated execution.
return (this.Ready_P = new Promise((resolve) => {
setTimeout(() => {
console.log('B Resolves');
resolve(true);
}, 2000);
}));
}
}
// A.ts is similar to C
完整代码见here。
注意:我希望我的 A、B、C 服务使用相同的模式进行理想编码。这些服务可能会也可能不会使用 http.get... 等来完成和准备一些数据。为简单起见,我使用 setTimeout() 来模拟它们将需要一些不同的时间才能完成。
预期的执行顺序
1. A Resolves
2. AService Ready from B
3. B Resolves
4. BService Ready from C
5. C Resolves
6. CService Ready from home
7. BService Ready from home
【问题讨论】:
-
承诺和
await或.then()。 -
鉴于我在这个 TS/JS hacking 中已经有一段时间了,我 100% 确信我永远不会完全掌握 Promises、Observable、Async/Await、rxjs 等事物的正确用法和本质, ... 但是,我有一个大致的理解,并且通过剪切/粘贴方法进行真正的编码,这在过去似乎对我有用。您能否很好地阐明您在 await 或以上的回答的意思。那么,我认为我没有将它们混入我的 plunkers 中。谢谢。
-
嗯,到目前为止,您在问题中显示的所有代码都只是脚手架 - 它并没有真正做任何事情。教授整个通用主题(如承诺)比解决特定的现实世界编码问题然后让您从该解决方案中学习要困难 100-1000 倍。如果您使用真实代码而不是伪代码或代码脚手架来展示真实世界的编码问题,那么我很乐意看到提供解决方案。但是,我不能真正尝试在一个问题的一个答案的范围内教授 Promise 和
async/await和.then()的一般概念。 -
在不理解基本概念的情况下通过剪切/粘贴进行编码不会产生好的、可靠的代码。花时间学习基本概念是值得的。这将为您带来回报。
-
并且,不要使用
http.get()向其他服务器发出http 请求。它的级别太低,不支持 Promise,并且需要大量额外的编码才能使其正常工作。相反,请获取像got()或axios()这样的库,以便更轻松地使用 Promise 进行编程。
标签: node.js angular typescript promise