RxJSサブジェクトのサブスクライブコールバック内で、await
関数でasync
を使用します。以下は、TypeScriptトランスパイラーが次のように文句を言うコード例です。
エラー:(131、21)TS2304:名前 '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
});
}
通常、async
以外の関数内でawaitを呼び出そうとすると、これが表示されます。何らかの方法でサブスクライブコールバックasync
を作成する必要がありますか、それとも間違っていますか?関数saveToDatabase
はasync
であり、書き込まれたデータベースの主キーに解決されるプロミスを返します。
サブスクライブの匿名関数呼び出しに非同期署名を直接追加できます
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
});
この問題を解決する私の方法は次のとおりです
const title = await new Promise<string>(resolve =>
this.translate.get('MYBOOK-PAGE.PAGE_TITLE')
.subscribe(translated => {
resolve(translated)
}));
ここで私がやっていることは私のオブザーバブルを約束に変えることです
注:ここで唯一の問題は、これが1回限りのショーであるということです。一度購読すると、再度アクセスできなくなります。ここで共有してくれました。
更新:一度だけ簡単に見られるのは、サブスクライバーの前でtoPromise
を使用するだけです (blog) 。したがって、上記の場合は次のようになります。
const title = await this.translate.get('MYBOOK-PAGE.PAGE_TITLE').toPromise();
おそらく、この問題に対する更新された応答。応答を待機する同様のニーズがあり、Observable実装内でawait
またはsetTimeout()メソッドを使用するのではなく、RxJSビルトインinterval()
メソッドを使用するのがよりクリーンな方法になりましたサブスクリプションを完了します。
サービスでこれを試してください:
import { interval } from 'rxjs';
...
// inside your method
const source = interval(100);
source.subscribe(x => {
subject.next(CONNECTIONS_DATA);
subject.complete();
});
return subject;
RxJS Docs: https://rxjs-dev.firebaseapp.com/guide/subject#reference-counting
誰かが最近これをやろうとしているなら、少しでも役に立てば幸いです。
await
Observablesを直接使用することはできませんが、await
a Promise
は使用できます。 observablesサブスクリプションで.toPromise()
メソッドを使用するだけです。以下を考慮してください。
async ngOnInit() {
const date = await dateSubscription.toPromise();
let dbKey = await this._someService.saveToDatabase(someObject);
}
await
の約束をdateSubscription
すると、Date
オブジェクトが渡されます。その後、実行の次の行に進むことができます。これにより、コードの読み取りがよりシーケンシャルになります。
一部の人々は、angularがngOnInit
の完了を待たず、選択肢がないと考えています。指定されたJavaScript
here から得られるTypeScript
を見てください。ご覧のとおり、ngOnInit
は、基礎となるステートマシン(ジェネレーター)を内部的に管理および実行するawaiterを呼び出します。 Angularはそれを制御できません。そのメソッドを呼び出すだけです。
以下を試すことができます:
ngOnInit() {
this.subscriber = dateSubscription.subscribe((date: Date) => {
(async () => {
let dbKey = await this._someService.saveToDatabase(someObject);
// ... some other code here
})();
});
}