Component.load() and Component.onload() are defined as void methods. However Plugin.onload is defined as Promise<void> | void
Reverse engineering Component.load() I see that it’s written assuming component can return Promise<void>, it uses Promise.all() internally.
We can define our components like
class MyComponent extends Component {
public override async onload(): Promise<void> {
}
}
but @typescript-eslint/no-misused-promises eslint rule will complain
I propose to change the Component API to
class Component {
public load(): Promise<void> | void;
public onload(): Promise<void> | void;
// ...
}
Then plugin writers can choose to override them with void or Promise<void> depending on their needs.
Current Component.load() implementation loads children in parallel and swallows all possible errors
Roughly speaking it’s implemented like
const childPromises: (Promise<void> | undefined)[] = [];
for (const child of this._children) {
childPromises.push(child.load() as Promise<void> | undefined);
}
Promise.all(childPromises).then();
Here we see that synchronous child.load() are executed sequentially, but asynchronous ones are executed in parallel, which might potentially cause some race conditions.
If you implement this FR, it will allow you to stop swallowing possible child promise rejections and consider loading async children sequentially.