angular - Hur man väntar inuti RxJS subscribe-metod
Inuti en RxJS subjects subscribe-callback vill jag await på en async funktion. Nedan är ett kodexempel som TypeScript-transpilern klagar på och säger:
Fel:(131, 21) TS2304:Kan inte hitta namnet 'await'.
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
});
}
Vanligtvis ser jag detta när jag försöker anropa await inuti en icke-async-funktion. Behöver jag på något sätt göra subscribe-callbacken async eller gör jag fel här? Funktionen saveToDatabase är async och returnerar ett löfte som löses till den primära nyckeln i databasen som skrevs till.
Svar #1
Du behöver inte använda await, och du behöver inte heller konvertera ditt Promise till en Observable.
Se detta Tweet från Ben Lesh :
Här är ett exempel med en mock för funktionen saveToDatabase :
(och den fungerande 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();
Utdata :
Svar #2
du kan bara direkt lägga till async-signatur till det anonyma funktionsanropet i 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
});
Svar #3
Uppdatering: Hittade enkelt för engångslöften, använd bara toPromise framför abonnenten (blogg). Så för ovanstående fall blir det så här:
const title = await this.translate.get('MYBOOK-PAGE.PAGE_TITLE').toPromise();
Gammalt sätt: Här är min metod för att lösa detta problem
const title = await new Promise<string>(resolve =>
this.translate.get('MYBOOK-PAGE.PAGE_TITLE')
.subscribe(translated => {
resolve(translated)
}));
Här gör jag är att ändra min Observable till ett Promise
Observera: Här är det enda problemet att detta är en engångsshow, dvs. om du prenumererar en gång kommer du inte kunna få åtkomst till det igen. Passade mig, så delar här.

