I'm building a game using Angular which has the following mechanics:
- An Angular service checks the game state and requests a required user interaction.
- A mediator service creates this request and emits it to the relevant Angular component using a RxJS subject.
- A response to this request is awaited in this mediator service, game doesn't go on until request is resolved.
- The component sets the user's response to the request through a call of
request.respond(response)
method.
I needed to come up with a Request class suitable for this requirements. As requests are resolved once and for all, I decided to avoid basing it on RxJs Observable, and tried using JavaScript Promise instead. Promises can be easly awaited with async
/await
syntax, and requirement (4) led me to find out about the Deferred pattern. I built this base class for all kinds of requests:
abstract class Request<T> {
private _resolve: (value: T) => void = () => {};
private _response: Promise<T> = new Promise<T>(resolve => {
this._resolve = resolve;
});
public get response(): Promise<T> {
return this._response;
}
public respond(response: T) {
this._resolve(response);
}
}
I didn't add rejection handling since I didn't come up with a situation when the request could fail. Not even a timeout seems to be needed, since the game requires a response to continue.
This worked perfectly for my purposes, but then I started to find discussions treating this as an anti-pattern (for example,this and this). I'm not used to working with promises, so I don't fully understand the risks of exposing the resolve function, I can't discern situations when this pattern would be legitimate, nor can I imagine some other way to meet my requirements using Promise.
I would like to know then if this is a legitimate way to use the Deferred pattern, and in case it is not, if there is another way to achieve what I need.