function debounce(func, delay) { let timeout; return function(...args) { const context = this; clearTimeout(timeout); timeout = setTimeout(() => func.apply(context, args), delay); }; } // Assume an API function that takes a query string async function searchApi(query) { if (!query) { console.log('Search query is empty, not calling API.'); return []; } console.log(`Searching for: ${query}...`); try { const response = await fetch(`https://api.example.com/search?q=${encodeURIComponent(query)}`); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); console.log('Search results:', data); return data; } catch (error) { console.error('Error during search:', error); throw error; } } // Debounced version of the search API call const debouncedSearch = debounce(async (query) => { try { const results = await searchApi(query); // Update UI with results } catch (error) { // Handle search error } }, 500); // 500ms delay // Example usage (e.g., in an input event listener): // document.getElementById('searchInput').addEventListener('input', (event) => { // debouncedSearch(event.target.value); // });