À l'intérieur du rappel d'abonnement d'un sujet RxJS, je souhaite await
sur une fonction async
. Vous trouverez ci-dessous un exemple de code que le transpiler TypeScript se plaint d'avoir à dire:
Erreur: (131, 21) TS2304: Impossible de trouver le nom 'wait'.
async ngOnInit() {
this.subscriber = dateSubscription.subscribe((date: Date) => {
let dbKey = await this._someService.saveToDatabase(someObject);
// wait for db write to finish before evaluating the next code
// ... some other code here
});
}
Habituellement, je vois cela lorsque j'essaie d'appeler une attente dans une fonction non async
. Dois-je en quelque sorte faire le rappel de souscription async
ou est-ce que je me trompe? La fonction saveToDatabase
est async
et renvoie une promesse résolue à la clé primaire de la base de données dans laquelle elle a été écrite.
Vous n'avez pas besoin d'utiliser await
, ni de convertir votre Promise
en Observable
.
Voici un exemple avec une maquette pour la fonction saveToDatabase
:
(et le serveur Plunkr: https://plnkr.co/edit/7SDLvRS2aTw9gYWdIznS?p=preview )
const { Observable } = Rx;
const saveToDatabase = (date) =>
new Promise(resolve =>
setTimeout(() =>
resolve(`${date} has been saved to the database`),
1000));
const date$ = Observable.of(new Date()).delay(1000);
date$
.do(x => console.log(`date received, trying to save it to database ...`))
.switchMap(date => saveToDatabase(date))
.do(console.log)
.subscribe();
vous pouvez simplement ajouter directement une signature asynchrone à l'appel de fonction anonyme de Subscribe
this.subscriber = dateSubscription.subscribe(async (date: Date) => {
let dbKey = await this._someService.saveToDatabase(someObject);
// wait for db write to finish before evaluating the next code
// ... some other code here
});
Voici ma méthode pour résoudre ce problème
const title = await new Promise<string>(resolve =>
this.translate.get('MYBOOK-PAGE.PLEASE_REMOVE')
.subscribe(translated => {
resolve(translated)
}));
Voici ce que je fais est en train de changer mon observable en une promesse
Remarque: Le seul problème est qu’il s’agit d’un spectacle unique. si tu abonnez-vous une fois que vous ne pourrez plus y accéder. Convient à moi pour partager ici.
Vous ne pouvez pas await
Observables directement, mais vous pouvez await
a Promise
. Vous pouvez simplement utiliser la méthode .toPromise()
sur l'abonnement observables. Considérer ce qui suit:
async ngOnInit() {
const date = await dateSubscription.toPromise();
let dbKey = await this._someService.saveToDatabase(someObject);
}
Lorsque vous await
la promesse de dateSubscription
, un objet Date
vous sera remis. Vous pouvez ensuite continuer avec la ligne suivante de votre exécution, ce qui rend la lecture de votre code plus séquentielle.
Certaines personnes pensent que l'angulaire n'attendra pas que la ngOnInit
soit complète, elle n'a pas le choix. Jetez un coup d’œil à la JavaScript
résultante de la TypeScript
ici . Comme vous pouvez le constater, la ngOnInit
invoquera l'attendeur qui gère et exécute en interne la machine à états sous-jacente (générateur). Angular n'a aucun contrôle sur ça. Il veut simplement que cette méthode soit invoquée.
Vous pouvez essayer ce qui suit:
ngOnInit() {
this.subscriber = dateSubscription.subscribe((date: Date) => {
(async () => {
let dbKey = await this._someService.saveToDatabase(someObject);
// ... some other code here
})();
});
}