EN/CH Mode
BRUCE_FE JS Interview Notes - Implementing Promise Sleep Function
Learn how to implement Promise Sleep function in JavaScript, handle delayed execution, scheduled tasks and animations, and master the fundamental tools of asynchronous programming.
EN/CH Mode
Lazy to read articles? Then watch videos!
Promise Sleep Function Overview
Promise Sleep function is a simple but practical tool that allows code to pause execution for a specified time. In various asynchronous operations, the sleep function is very useful, especially when you need to delay execution, simulate network delays, or control animation timing.
Why Do We Need Sleep Function?
- 1.
Control Execution Rhythm
: Add delays between consecutive operations to avoid overly frequent operations - 2.
Simulate Network Delay
: Test code's ability to handle delays - 3.
Animation and Visual Effects
: Control intervals between consecutive visual changes - 4.
API Rate Limiting
: Avoid sending too many requests in a short time - 5.
Retry Mechanism
: Implement retry strategies like exponential backoff
Basic Promise Sleep Implementation
Below is a simple Promise Sleep function implementation:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Usage example
async function example() {
console.log('Start');
await sleep(2000); // Pause for 2 seconds
console.log('After 2 seconds'); // Execute after 2 seconds
}
example();
This function creates a new Promise that calls resolve after the specified milliseconds. Combined with async/await syntax, it allows code to pause execution for a specified time.
Advanced Promise Sleep Features
We can extend the basic sleep function to add more features:
Sleep with Return Value
function sleepWithValue(ms, value) {
return new Promise(resolve => setTimeout(() => resolve(value), ms));
}
// Usage example
async function example() {
console.log('Start');
const result = await sleepWithValue(2000, 'Delayed returned data');
console.log(result); // Display after 2 seconds: Delayed returned data
}
example();
Cancellable Sleep
function cancellableSleep(ms) {
let timeoutId;
const promise = new Promise(resolve => {
timeoutId = setTimeout(resolve, ms);
});
// Add cancel method
promise.cancel = function() {
clearTimeout(timeoutId);
};
return promise;
}
// Usage example
async function example() {
console.log('Start');
const sleepPromise = cancellableSleep(5000);
// Cancel sleep after 2 seconds
setTimeout(() => {
console.log('Cancel sleep');
sleepPromise.cancel();
}, 2000);
try {
await sleepPromise;
console.log('After 5 seconds'); // Won't execute because cancelled
} catch (error) {
console.log('Sleep was cancelled');
}
}
example();
Practical Application Scenarios
Here are some practical applications of Promise Sleep function:
1. Implementing API Request Retry Mechanism
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
const { retryDelay = 1000 } = options;
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
// Try to make request
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.log(`Attempt ${attempt + 1} failed: ${error.message}`);
lastError = error;
if (attempt < maxRetries - 1) {
// Use exponential backoff strategy to calculate next retry delay
const delay = retryDelay * Math.pow(2, attempt);
console.log(`Waiting ${delay}ms before retry...`);
await sleep(delay);
}
}
}
throw lastError;
}
// Usage example
async function getData() {
try {
const data = await fetchWithRetry('https://api.example.com/data');
console.log('Successfully fetched data:', data);
} catch (error) {
console.error('All retries failed:', error);
}
}
getData();
2. Creating Animation Sequences
async function animateSequence(element) {
// Set initial state
element.style.opacity = '0';
element.style.transform = 'translateY(20px)';
element.style.transition = 'all 0.5s ease-out';
// Ensure element is visible
element.style.display = 'block';
// Wait one frame to ensure transition effects take effect
await sleep(50);
// Fade in animation
element.style.opacity = '1';
element.style.transform = 'translateY(0)';
// Wait for fade in to complete
await sleep(500);
// Add emphasis effect
element.style.transform = 'scale(1.1)';
await sleep(200);
// Restore normal size
element.style.transform = 'scale(1)';
}
// Usage example
document.getElementById('showButton').addEventListener('click', () => {
const notification = document.getElementById('notification');
animateSequence(notification);
});
3. Rate Limiting API Requests
class RateLimiter {
constructor(requestsPerSecond) {
this.minDelayMs = 1000 / requestsPerSecond;
this.lastRequestTime = 0;
}
async limit() {
const now = Date.now();
const timeElapsed = now - this.lastRequestTime;
if (timeElapsed < this.minDelayMs) {
// Calculate wait time needed
const waitTime = this.minDelayMs - timeElapsed;
await sleep(waitTime);
}
this.lastRequestTime = Date.now();
}
}
// Usage example - Maximum 2 requests per second
const limiter = new RateLimiter(2);
async function fetchWithRateLimit(url) {
await limiter.limit();
return fetch(url).then(res => res.json());
}
// Demonstrate multiple calls
async function fetchMultipleData() {
console.log('Start fetching data...');
// These requests will be rate limited, maximum 2 per second
const results = await Promise.all([
fetchWithRateLimit('https://api.example.com/1'),
fetchWithRateLimit('https://api.example.com/2'),
fetchWithRateLimit('https://api.example.com/3'),
fetchWithRateLimit('https://api.example.com/4')
]);
console.log('All data fetched', results);
}
fetchMultipleData();