Dipublikasikan 24 Mei 2026
Async programming di JavaScript sudah jadi standar, tapi banyak code yang masih rentan terhadap network failure dan timeout. Tutorial dari DaniKeya di Dev.to menunjukkan bahwa dua function sederhana saja bisa membuat async code production-ready. Artikel ini akan membahas implementasi pattern retry dan timeout untuk async JavaScript.
Network tidak selalu reliable. API bisa down sementara, connection bisa timeout, atau rate limit bisa mengembalikan error sementara. Tanpa retry, aplikasi kamu akan langsung gagal. Tanpa timeout, aplikasi bisa menunggu response yang tidak pernah datang.
Dua function yang akan kita bangun adalah retry dan timeout. Function ini reusable dan bisa di-attach ke async operation apa pun.
Function timeout memberikan batas waktu eksekusi pada async operation. Jika operation melebihi batas waktu, Promise akan reject dengan error timeout.
function timeout(promise, ms) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('Operation timed out'));
}, ms);
promise.then((value) => {
clearTimeout(timer);
resolve(value);
}).catch((error) => {
clearTimeout(timer);
reject(error);
});
});
}
Penggunaannya sederhana: bungkus Promise dengan timeout wrapper.
const result = await timeout(fetchUserData(), 5000);
Jika fetchUserData tidak selesai dalam 5 detik, Promise akan reject.
Retry tidak cukup hanya dengan mengeksekusi ulang. Kita perlu exponential backoff untuk menghindari thundering herd problem dan memberikan waktu bagi service untuk recover.
async function retry(fn, { retries = 3, delay = 1000, backoff = 2 } = {}) {
try {
return await fn();
} catch (error) {
if (retries === 0) throw error;
await new Promise(resolve => setTimeout(resolve, delay));
return retry(fn, { retries: retries - 1, delay: delay * backoff, backoff });
}
}
Function ini secara rekursif memanggil operation dengan delay yang meningkat secara eksponensial. Parameter retries, delay, dan backoff bisa dikustomisasi sesuai kebutuhan.
const result = await retry(() => fetch('/api/data'), {
retries: 5,
delay: 1000,
backoff: 2
});
Timeout dan retry paling powerful ketika digunakan bersamaan. Retry akan menangani transient failures, sementara timeout mencegah operation terjebak terlalu lama.
async function fetchWithRetryAndTimeout(url, options = {}) {
const { retries = 3, timeoutMs = 5000 } = options;
return retry(
() => timeout(fetch(url), timeoutMs),
{ retries, delay: 1000, backoff: 2 }
);
}
Function ini memberikan 3 kali retry dengan exponential backoff, dan setiap attempt dibatasi 5 detik. Ini adalah pattern yang sangat umum di production code.
Pattern ini bisa di-extract menjadi custom hook atau utility module. Berikut contoh custom hook untuk React:
import { useState, useEffect } from 'react';
function useAsyncWithRetry(fn, deps, options = {}) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
async function execute() {
try {
const result = await retry(() => timeout(fn(), options.timeout || 5000), {
retries: options.retries || 3,
delay: 1000,
backoff: 2
});
if (!cancelled) setData(result);
} catch (err) {
if (!cancelled) setError(err);
} finally {
if (!cancelled) setLoading(false);
}
}
execute();
return () => { cancelled = true; };
}, deps);
return { data, error, loading };
}
Custom hook ini menangani cleanup saat component unmount, sehingga tidak ada state update pada component yang sudah tidak ada.
Pattern retry dan timeout adalah fondasi untuk async code yang resilient di production. Dengan hanya dua function kecil, kamu sudah bisa menangani transient failures dan prevent hanging operations. Source lengkap dan penjelasan detail bisa dilihat di tutorial asli Dev.to - Retry dan Timeout Functions.
Dapatkan feedback, users, dan eksposur dari komunitas kreator, developer, dan entrepreneur digital Indonesia.
Submit Produk → Pelajari Dulu