В моем проекте Angular 5 есть служба, которая содержит некоторое состояние конфигурации:
@Injectable
export class FooService {
isIncognito: boolean = null;
constructor() {
// I want Angular to wait for this to resolve (i.e. until `isIncognito != null`):
FooService.isIncognitoWindow()
.then( isIncognito => {
this.isIncognito= isIncognito;
} );
}
private static isIncognitoWindow(): Promise<boolean> {
// /1490063/mozhete-li-vy-opredelit-nahoditsya-li-chrome-v-rezhime-inkognito-s-pomoschy-stsenariya
// https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem
return new Promise<boolean>( ( resolve, reject ) => {
let rfs = window['requestFileSystem'] || window['webkitRequestFileSystem'];
if( !rfs ) {
console.warn( "window.RequestFileSystem not found." );
resolve( false );
}
const typeTemporary = 0;
const typePersistent = 1;
// requestFileSystem's callbacks are made asynchronously, so we need to use a promise.
rfs(
/*type: */ typeTemporary,
/* bytesRequested: */ 100,
/* successCallback: */ function( fso: WebKitFileSystem ) {
resolve( false );
},
/* errorCallback: */ function( err: any /* FileError */ ) {
resolve( true );
}
);
} );
}
}
Этот сервис используется многими компонентами в моем проекте и передается в качестве аргумента конструктора. Например:
@Component( {
moduleId: module.id,
templateUrl: 'auth.component.html'
} )
export class AuthComponent implements OnInit {
constructor( private fooService: FooService ) {
}
ngOnInit(): void {
// do stuff that depends on `this.fooService.isIncognito != null`
}
}
В идеале я бы хотел, чтобы Angular дождался разрешения FooService::isIncognitoWindow()
(разрешение происходит мгновенно, но не синхронно), прежде чем вводить FooService
в другие компоненты.
Альтернативное решение - изменить свойство FooComponent.isIncognito
на Promise<boolean>
, разрешить его снова и вызвать остальную часть ngOnInit
с помощью обратного вызова, но это означает, что каждый компонент вызовет повторную активацию основной функции обещания. - таким образом, это означает, что вместо этого можно изменить его на буферизованный Observable или Subject, и это становится излишне сложным - все для одного значения boolean
. Это также означает рефакторинг большого количества кода, который я бы предпочел не делать.