{#await} adalah blok template yang menunggu sebuah Promise dan menampilkan salah satu dari tiga keadaan: selagi menunggu, saat berhasil, atau saat gagal. Promise adalah objek JavaScript yang mewakili hasil yang belum ada: nanti dia berhasil (resolve) dengan sebuah nilai, atau gagal (reject) dengan sebuah error. Bayangin pesan Nasi Goreng di Warung Bu Sri dan dapat kertas nomor antrean. Kertas itu bukan makanannya, tapi janji makanan. Selagi menunggu, papan di dinding menulis "Sedang dimasak". Kalau sudah jadi, piringnya datang. Kalau gasnya habis, pelayan bilang "Maaf, gak bisa". Kertasnya Promise, dan papan itu blok {#await}.
🧪 Tebakan cepat:
ambilMenu()gagal dengannew Error("Server warung sedang tutup"). Templatenya cuma punya{#await promise}dan{:then menu}, tanpa{:catch}. Setelah 800 ms, yang tampilMemuat menu...terus, pesan error-nya, atau kosong? Jawabannya ada di bagian "Tanpa {:catch}".
Tiga keadaan dalam satu blok
ambilMenu() pura-pura meminta menu ke server, dan server-nya menjawab setelah 800 ms:
<script>
function ambilMenu() {
return new Promise((berhasil) => {
setTimeout(() => {
berhasil([
{ nama: "Nasi Goreng", harga: 15000 },
{ nama: "Mie Ayam", harga: 12000 },
{ nama: "Es Teh", harga: 5000 },
])
}, 800)
})
}
let promise = ambilMenu()
</script>
{#await promise}
<p>Memuat menu...</p>
{:then menu}
<ul>
{#each menu as m}
<li>{m.nama} Rp {m.harga.toLocaleString("id-ID")}</li>
{/each}
</ul>
{:catch error}
<p>Gagal: {error.message}</p>
{/await}
| Waktu | Keadaan promise | Tampil |
|---|---|---|
| 0 ms | menunggu (pending) | Memuat menu... |
| 800 ms | berhasil | Nasi Goreng Rp 15.000, Mie Ayam Rp 12.000, Es Teh Rp 5.000 |
{#await promise}membuka bloknya. Isi sampai{:then}tampil selama promise-nya belum selesai.{:then menu}tampil saat promise berhasil. Nilai hasilnya diberi namamenu; namanya bebas.{:catch error}tampil saat promise gagal.erroradalah alasan gagalnya, biasanya objekError, jadi pesannya dibaca denganerror.message.{/await}menutup bloknya. Polanya sama dengan{#if}dan{#each}:#membuka,:melanjutkan,/menutup.- Di pelajaran Lifecycle, hal yang sama butuh
onMount,menu = await ambilMenu(), dan{#if menu.length === 0}. Di sini gak ada variabel tambahan, dan cabang gagalnya ikut tersedia.
Kalau gagal: {:catch}
Sekarang server-nya tutup:
function ambilMenu() {
return new Promise((berhasil, tolak) => {
setTimeout(() => tolak(new Error("Server warung sedang tutup")), 800)
})
}
Di 0 ms tetap Memuat menu.... Di 800 ms, cabang {:catch error} menggantikannya: Gagal: Server warung sedang tutup.
Di aplikasi sungguhan, promise-nya biasanya datang dari fetch("/api/menu").then((r) => r.json()). Ingat, fetch cuma gagal kalau jaringannya putus. Jawaban 404 atau 500 tetap dianggap berhasil, kecuali kamu sendiri menulis if (!r.ok) throw new Error("Gagal memuat menu").
Tanpa {:catch}
Template yang sama tanpa {:catch}. Di 800 ms, Svelte membuang Memuat menu..., gak ada cabang yang bisa ditampilkan, jadi bagian itu kosong. Itu jawaban tebakannya. Error-nya gak hilang: Svelte melemparnya lagi, dan console menulis Uncaught (in promise) Error: Server warung sedang tutup. Pembeli cuma melihat halaman kosong tanpa penjelasan. Kalau promise-nya bisa gagal, selalu tulis {:catch}.
Muat ulang: tugaskan promise baru
<button on:click={() => (promise = ambilMenu())}>Muat ulang</button>
promise = ambilMenu()adalah assignment, jadi Svelte melihat promise baru. Bloknya kembali keMemuat menu..., lalu ke{:then}atau{:catch}sesuai hasil promise baru itu.on:click={ambilMenu}saja gak mengubah apa pun di layar. Function-nya jalan, tapi variabelpromisegak ditugaskan ulang.- Kalau tombolnya diklik dua kali dan permintaan pertama lebih lambat, Svelte cuma menampilkan hasil promise yang terakhir ditugaskan. Hasil yang lama dibuang saat datang.
Bentuk pendek
{#await promise then menu}
<p>{menu.length} menu tersedia</p>
{/await}
{#await promise then menu}gak punya cabang menunggu: selama 800 ms gak ada yang tampil, lalu3 menu tersedia.{#await promise catch error}adalah kebalikannya: cuma tampil kalau gagal.- Kalau yang ditunggu bukan Promise, misalnya
{#await 42}, bloknya langsung masuk{:then}.
Latihan: tiga keadaan
<script>
let promise = new Promise(resolve => {
setTimeout(() => resolve("Data berhasil dimuat!"), 100)
})
</script>
{#await promise}
<p>Loading...</p>
{:then data}
<p>{data}</p>
{:catch error}
<p>Error: {error.message}</p>
{/await}
Selama 100 ms paragrafnya Loading..., lalu Data berhasil dimuat!. Penguji menunggu sampai ada <p> yang memuat kata Data.
Svelte 5
Sintaks {#await} sama persis di Svelte 5. Bedanya cuma di variabelnya: di komponen runes, tulis let promise = $state(ambilMenu()), supaya promise = ambilMenu() di tombol Muat ulang memicu blok-nya lagi.
⚠️ Jebakan yang sering ketemu
- Gak menulis
{:catch}. Saat gagal, bagiannya kosong dan error-nya cuma muncul di console sebagaiUncaught (in promise). - Memanggil ulang tanpa assignment.
ambilMenu()saja gak memicu apa-apa. Tulispromise = ambilMenu(). awaitlangsung di<script>.let menu = await ambilMenu()di Svelte 4 lolos compile, tapi komponennya gagal dijalankan denganSyntaxError, karena<script>komponen bukan function async. Simpan promise-nya, lalu serahkan ke{#await}.- Cabang yang kurang. Latihannya memeriksa
#await,:then, dan:catchdi kodemu, dan<p>yang akhirnya memuatData.
TL;DR: {#await promise} ... {:then menu} ... {:catch error} ... {/await} menampilkan satu dari tiga keadaan Promise: menunggu, berhasil (nilainya jadi menu), atau gagal (alasannya jadi error, pesannya error.message). Tanpa {:catch}, promise yang gagal meninggalkan bagian kosong dan Uncaught (in promise) di console. Muat ulang dengan menugaskan promise baru, promise = ambilMenu(); Svelte cuma menampilkan hasil promise terakhir. {#await promise then menu} adalah bentuk pendek tanpa cabang menunggu. Di Svelte 5 sintaksnya sama, dengan $state untuk promise-nya. Latihannya: <p>Loading...</p>, lalu <p>{data}</p> yang menampilkan Data berhasil dimuat!, dan <p>Error: {error.message}</p> di {:catch error}.