Annulation
CancelToken est un signal d'annulation coopératif à usage unique. Le passer à fetchQuery, watchQuery ou prefetch et appeler cancel() pour interrompre le fetch avant son démarrage ou pendant son exécution.
Créer un token
final token = CancelToken();
Un token ne peut être annulé qu'une seule fois. Appeler cancel() une deuxième fois est sans effet.
Annuler un fetchQuery
final token = CancelToken();
// Démarrer le fetch
final future = client.fetchQuery<User>(
key: ['users', userId],
fetcher: () => api.getUser(userId),
cancelToken: token,
);
// L'annuler (ex. l'utilisateur a navigué ailleurs)
token.cancel();
try {
final user = await future;
} on QoraCancelException catch (e) {
// e.key est la clé de requête encodée en chaîne
print('Fetch annulé : ${e.key}');
}
Quand annulé, fetchQuery lève QoraCancelException à l'appelant et restaure l'entrée de cache à son snapshot pré-fetch (aucun état partiel n'est laissé derrière).
Annuler un stream watchQuery
final token = CancelToken();
final sub = client.watchQuery<User>(
key: ['users', userId],
fetcher: () => api.getUser(userId),
cancelToken: token,
).listen((state) { ... });
// Au dispose du widget : annuler le fetch en cours
token.cancel();
await sub.cancel();
token.cancel() interrompt la requête HTTP ; sub.cancel() retire le listener d'état. Faire les deux au dispose pour un nettoyage propre.Pattern de timeout
Combiner CancelToken avec Future.delayed pour implémenter un timeout de requête :
Future<User> fetchWithTimeout(int userId, Duration timeout) async {
final token = CancelToken();
Timer(timeout, token.cancel);
try {
return await client.fetchQuery<User>(
key: ['users', userId],
fetcher: () => api.getUser(userId),
cancelToken: token,
);
} on QoraCancelException {
throw TimeoutException('Fetch utilisateur expiré après $timeout');
}
}
Annulation à la navigation dans Flutter
Dans un StatefulWidget, lier le token au cycle de vie du widget :
class _UserScreenState extends State<UserScreen> {
CancelToken? _fetchToken;
Future<void> _loadUser() async {
_fetchToken = CancelToken();
try {
await context.qora.fetchQuery<User>(
key: ['users', widget.userId],
fetcher: () => api.getUser(widget.userId),
cancelToken: _fetchToken,
);
} on QoraCancelException {
// Widget disposé : ignorer
}
}
@override
void dispose() {
_fetchToken?.cancel();
super.dispose();
}
}
API CancelToken
Constructeur
CancelToken()
Propriétés
| Propriété | Type | Description |
|---|---|---|
isCancelled | bool | true après l'appel à cancel(). |
Méthodes
| Méthode | Signature | Description |
|---|---|---|
cancel() | void | Marque le token comme annulé. Idempotent et sûr à appeler plusieurs fois. |
QoraCancelException
Levée par fetchQuery et prefetch quand un fetch est annulé via CancelToken.
class QoraCancelException implements Exception {
final String key; // clé de requête normalisée encodée en JSON
}
| Propriété | Type | Description |
|---|---|---|
key | String | La clé de requête encodée en chaîne, ex. '["users",1]' |
Hook du tracker
QoraTracker.onQueryCancelled(String key) est appelé chaque fois qu'un fetch est annulé via CancelToken. L'implémenter sur un tracker personnalisé pour journaliser ou mesurer les taux d'annulation :
class AnalyticsTracker extends NoOpTracker {
@override
void onQueryCancelled(String key) {
analytics.track('query_cancelled', {'key': key});
}
}
Voir aussi
- API QoraClient : Signatures de
fetchQuery,watchQuery,prefetch - QoraTracker : Hooks d'observabilité
Requêtes dépendantes
Utiliser QoraOptions.dependsOn pour chaîner les requêtes de sorte qu'une ne se déclenche qu'après la résolution d'une autre.
Hydratation SSR
Éliminer le flash de chargement sur les pages Flutter Web rendues côté serveur en injectant le cache serveur dans QoraClient via SsrHydrator.