Это то, для чего используется отложенный шаблон. Он был реализован в jQuery и может быть antipattern , но имеет свои применения.
По существу, отложенное может быть возвращено вместо обещания, это похоже на то, что в настоящее время делает MapService
, но будет один отложенный объект, который отвечает за обработку этого обещания:
class Deferred<T = {}> {
resolve!: (val: T) => void;
reject!: (err: any) => void;
promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
@Injectable()
export class MapService {
mapView = new Deferred<__esri.MapView>();
}
Поскольку это вопрос Angular, следует заметить, что RxJS постоянно используется в приложениях Angular. Это может быть воспринято как альтернатива обещаниям, которые делают все, что обещания делают, и даже больше. Прямой аналог отсрочек и в RxJS - AsyncSubject
. Когда тема завершена, она выдает подписчикам одно значение.
Так будет:
@Injectable()
export class MapService {
mapView = new AsyncSubject<__esri.MapView>();
}
Это должно быть решено с помощью:
mapService.mapView.next(...);
mapService.mapView.complete();
Если оно уже используется в качестве обещания, AsyncSubject
можно легко переключить на обещание, поскольку это наблюдаемое, которое дополняется одним значением:
const view = await mapService.mapView.toPromise();
В представлениях как наблюдаемые, так и обещания могут обрабатываться async
pipe, {{ mapService.mapView | async }}
.
Кажется, это работает, но похоже на очень "хакерский" подход и неправильное использование обещаний.
Существует вероятность того, что обещание используется не по назначению, и это превращается в антипаттерн, как это часто бывает в случае отсрочек.
Служба Angular может выступать в качестве модели MV *, поэтому MapService
не должен принимать картографические данные извне, но должен отвечать за инициализацию и содержание картографических данных. В этом случае он должен создавать экземпляр MapView
во время инициализации приложения и предоставлять обещание MapView
экземпляр.