Skip to main content

await

Depuis la version 5.36 de Svelte, vous pouvez le mot-clé await dans vos composants à trois endroits où ce n’est pas possible précédemment :

  • à la racine du <script> de votre composant
  • dans des déclarations $derived(...)
  • dans votre markup

Cette fonctionnalité est actuellement expérimentale, et vous devez l’activer en ajoutant l’option experimental.async là où vous configurez Svelte, en général svelte.config.js :

svelte.config
export default {
	
compilerOptions: {
    experimental: {
        async: boolean;
    };
}
compilerOptions
: {
experimental: {
    async: boolean;
}
experimental
: {
async: booleanasync: true } } };

Le drapeau expérimental sera supprimé avec Svelte 6.

Frontières

Actuellement, vous pouvez uniquement utiilser await au sein d’un balise <svelte:boundary> ayant un snippet pending :

<svelte:boundary>
	<MyApp />

	{#snippet pending()}
		<p>chargement...</p>
	{/snippet}
</svelte:boundary>

Cette restriction sera levée lorsque Svelte supportera le rendu côté serveur asynchrone (voir les mises en garde).

Dans le bac à sable, votre application est rendue au sein d’une frontière ayant un snippet pending vide, afin que vous puissez utiliser await sans avoir à en créer un.

Mises à jour synchronisées

Lorsqu’une expression await dépend d’un morceau d’état particulier, les changements de cet état ne seront pas reflétés dans l’interface avant que le travail asynchrone ne soit terminé, afin que l’interface ne soit pas laissée dans un état inconsistant. En d’autres mots, dans un exemple comme celui-ci...

<script>
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // délai artificiel
		return a + b;
	}
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {await add(a, b)}</p>

... si vous incrémentez a, le contenu de <p> ne sera pas immédiatement mis à jour et n’affichera donc pas ceci —

<p>2 + 2 = 3</p>

— mais à la place, le texte affichera 2 + 2 = 4 lorsque add(a, b) sera résolue.

Les mises à jour peuvent se superposer — une mise à jour rapide sera reflétée dans l’interface tandis qu’une mise à jour lente sera toujours en cours.

Concurrence

Svelte fera autant de travail asynchrone que possible en parallèle. Par exemple, si vous avez deux expressions await dans votre markup...

<p>{await one()}</p>
<p>{await two()}</p>

... les deux fonctions seront exécutées en mêmet temps, puisque ce sont des expressions indépendantes, même si elles sont visuellement séquentielles.

Ceci ne s’applique pas aux expressions await de votre <script> ou dans les fonctions asynchrones — celles-ci s’exécutent comme tout autre code JavaScript asynchrone. Toutefois, il y a une exception : les expressions $derived indépendantes seront mises à jour indépendamment, même si elles sont exécutées séquentiellement lors de leur création :

// ces expressions sont exécutées séquentiellement la première fois
// mais seront mises à jour indépendamment
let let a: numbera = 
function $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables. The expression inside $derived(...) should be free of side-effects.

Example:

let double = $derived(count * 2);

https://svelte.dev/docs/svelte/$derived

@paramexpression The derived state expression
$derived
(await function one(): Promise<number>one());
let let b: numberb =
function $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables. The expression inside $derived(...) should be free of side-effects.

Example:

let double = $derived(count * 2);

https://svelte.dev/docs/svelte/$derived

@paramexpression The derived state expression
$derived
(await function two(): Promise<number>two());

Si vous écrivez du code comme celui-là, attendez-vous à ce que Svelte vous affiche un avertissement await_waterfall

Indiquer les états de chargement

En plus du snippet pending de la frontière la plus proche, vous pouvez indiquer que du travail asynchrone est en cours avec la rune $effect.pending().

Vous pouvez aussi utiliser settled() pour obtenir une promesse qui se résout lorsque la mise à jour actuelle se termine :

import { function tick(): Promise<void>

Returns a promise that resolves once any pending state changes have been applied.

tick
, import settledsettled } from 'svelte';
async function function onclick(): Promise<void>onclick() { let updating: booleanupdating = true; // sans ceci, le changement à `updating` sera groupé // avec les autres changements, signifiant qu'il ne sera // pas reflété dans l'interface await function tick(): Promise<void>

Returns a promise that resolves once any pending state changes have been applied.

tick
();
let color: stringcolor = 'octarine'; let answer: numberanswer = 42; await import settledsettled(); // toute mise à jour affectée par `color` ou `answer` // a désormais été appliquée let updating: booleanupdating = false; }

Gestion des erreurs

Les erreurs dans les expressions await vont remonter jusqu’à la frontière d’erreur la plus proche.

Mises en garde

En tant que fonctionnalité expérimentale, les détails de comment les expressions await sont gérées (ainsi que les APIs liées comme $effect.pending()) sont potentiellement sujettes à des breaking changes en dehors d’un changement de version majeur, même si nous avons l’intention de limiter ces changements au minimum.

Actuellement, le rendu côté serveur reste synchrone. Si une balise <svelte:boundary> ayant un snippet pending est rencontrée lors du SSR, seul le snippet pending sera affiché.

Breaking changes

Les effets sont exécutées dans un ordre légèrement différent lorsque l’option experimental.async est à true. Spécifiquement, les effets de block comme {#if ...} et {#each ...} s’exécutent désormais avant un $effect.pre ou un beforeUpdate du même composant, ce qui implique que dans de très rares situations il est possible de mettre à jour un bloc qui ne devrait pas exister, mais uniquement si vous mettez à jour un état au sein d’un effet, ce que vous devriez éviter.

Modifier cette page sur Github llms.txt

précédent suivant