ストリーミングクエリ
streamedQuery は Stream をクエリ関数に変えます。チャンクが届いている間、画面はデータを表示します。ストリームが終わると、キャッシュが結果を保持します。
ストリーミングで返る回答、進捗ログ、処理中のファイルなど、チャンクで届いて最後に終わるレスポンスに使ってください。ライブフィードのように開いたままの接続は取得ではないので、クエリには向きません。その場合は、キャッシュを読み書きするのように、各メッセージを setQueryData でキャッシュに書き込んでください。
final answer = Query( queryKey: ['answer', question], queryFn: streamedQuery( stream: (context) => api.ask(question), initialValue: '', combine: (text, token) => text + token, ),);- 最初のチャンクでクエリが成功します。データが増えるにつれて、ウィジェットがそのデータを表示します。
- ストリームが終わるまで
isFetchingは true のままです。 combineはStream.foldと同じように動きます。initialValueから始めて、それまでの値にチャンクを 1 つずつ加えます。initialValueがデータ型を決めるので、呼び出しに型引数は不要です。- 空のストリームは
initialValueで成功します。 - ストリームや
combineでエラーが起きると、クエリは失敗します。dataには、それまでに受け取ったチャンクが残ります。 - 再試行のたびに新しいストリームを開始し、
refetchModeに従います。デフォルトのモードでは、最初にデータを消去します。
Query は、staleTime などのほかのクエリのオプションも通常どおり受け取ります。
チャンクをリストに集める
Section titled “チャンクをリストに集める”空のリストから始めて、各チャンクを追加してください。
final log = Query( queryKey: ['jobs', id, 'log'], queryFn: streamedQuery( stream: (context) => api.jobLog(id), initialValue: const <LogLine>[], combine: (lines, line) => [...lines, line], ),);ストリーミングクエリを再取得する
Section titled “ストリーミングクエリを再取得する”refetchMode は、invalidateQueries の後などにクエリがもう一度取得するとき、キャッシュされたデータをどう扱うかを決めます。
| モード | 新しいストリームの実行中 | 完了時 |
|---|---|---|
StreamRefetchMode.reset(デフォルト) |
Fuery がデータを消去し、最初のチャンクが届くまでクエリは pending になります。 | 新しいデータ |
StreamRefetchMode.append |
Fuery が新しいチャンクを既存のデータに畳み込みます。 | 結合されたデータ |
StreamRefetchMode.replace |
古いデータが画面に残ります。 | 新しいデータ(一度にまとめて) |
queryFn: streamedQuery( stream: (context) => api.ask(question), initialValue: '', combine: (text, token) => text + token, refetchMode: StreamRefetchMode.replace,),ストリームを止める
Section titled “ストリームを止める”Fuery は、取得をキャンセルするときにストリームもキャンセルします。cancelQueries のときと、再取得が実行中の取得を置き換えるときです。
デフォルトでは、どのウィジェットもクエリを使っていなくてもストリームは動き続け、Fuery が結果をキャッシュします。そのため、ユーザーが戻ってきたときには、ストリーミングの回答は完成しています。代わりにストリームを止めるには、stream の中で context.signal を読んでください。すると、取得がキャンセル可能になります。
stream: (context) { final request = api.startAnswer(question); // a request you can cancel context.signal.onAbort(request.cancel); return request.tokens;},サンプルアプリでは
Section titled “サンプルアプリでは”サンプルアプリは、投稿画面でスレッドの要約をストリーミングしています。README では、各画面とその画面で示している機能を対応づけています。