JavaScript is a single-threaded, non-blocking language, which means that it can handle asynchronous operations efficiently without blocking the main execution thread. Understanding timing and asynchronous operations is crucial for developing responsive web applications. This note provides an overview of timing mechanisms, asynchronous programming patterns, and ES6+ features that facilitate these operations.
- Timing Mechanisms
- setTimeout
- setInterval
- requestAnimationFrame
- Asynchronous Programming
- Callbacks
- Promises
- Async/Await
JavaScript provides several built-in functions for managing timing events.
setTimeout
allows you to execute a function after a specified delay (in milliseconds).
setTimeout(() => {
console.log('Executed after 2 seconds');
}, 2000);
setInterval
is used to repeatedly execute a function with a fixed time interval.
const intervalId = setInterval(() => {
console.log('Executed every 1 second');
}, 1000);
// To stop the interval
clearInterval(intervalId);
requestAnimationFrame
is a built-in function that allows you to execute a function before the next repaint. This is useful for creating smooth animations and other visual effects.
function animate() {
console.log('Animation frame');
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
In modern JavaScript (ES6+), several patterns and features facilitate asynchronous programming.
Callbacks are functions passed as arguments to other functions that execute once an asynchronous operation has completed.
function fetchData(callback) {
setTimeout(() => {
const data = 'Data fetched';
callback(data);
}, 1000);
}
fetchData((data) => {
console.log(data); // 'Data fetched'
});
Promises provide a cleaner way to handle asynchronous operations, avoiding callback hell. A promise can be in one of three states: pending, fulfilled, or rejected.
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Data fetched';
resolve(data);
}, 1000);
});
};
fetchData()
.then((data) => {
console.log(data); // 'Data fetched'
})
.catch((error) => {
console.error(error);
});
The async
and await
keywords, introduced in ES2017
, allow you to write asynchronous code that looks and behaves like synchronous code.
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
const data = 'Data fetched';
resolve(data);
}, 1000);
});
};
const fetchDataAsync = async () => {
const data = await fetchData();
console.log(data); // 'Data fetched'
};
fetchDataAsync();
Tip
Use async
/await
for Cleaner Code:
With async
/await
, you can write asynchronous code that looks and behaves like synchronous code, making it more readable and easier to maintain. Always remember to handle errors with try
...catch
blocks when using await
. This way, if an asynchronous operation fails, you can gracefully handle the error without crashing your application.
Example:
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
[EOF]