Question 28
Question
What is the difference between async iterators, generators, promises, and observables?
Answer
1. Generators:
Purpose: Functions that produce sequences of values lazily. They pause execution, yield a value, and resume from where they left off when the next value is requested.
Mechanism: Use
function*
to define them. Inside, useyield
to return a value and pause execution.next()
is called to retrieve the next yielded value.
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next()); // Output: {value: 1, done: false}
console.log(gen.next()); // Output: {value: 2, done: false}
Use Cases: Generating sequences of data, simplifying iterative processes, creating custom iterables.
2. Async Iterators:
Purpose: Similar to generators but handle asynchronous operations. They pause execution until a promise resolves and yield the result.
Mechanism: Defined using
async function*
and useawait
inside to wait for promises.Use Cases: Processing asynchronous data streams efficiently, working with APIs that return data in chunks.
async function* fetchData() {
yield await fetch('https://api.example.com/data');
yield await fetch('https://api.example.com/moreData');
}
const iterator = fetchData();
iterator.next().then(data => console.log(data.value)); // Log first fetched data
3. Promises:
Purpose: Represent the eventual result of an asynchronous operation (success or failure). They have states: pending, fulfilled (success), rejected (failure).
Mechanism: Created with
new Promise()
. Resolve with.resolve()
when successful or reject with.reject()
on failure.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Success!'), 2000); // Simulate async operation
});
promise.then(result => console.log(result)) // Handle success
.catch(error => console.error(error)); // Handle failure
Use Cases: Handling asynchronous tasks, managing error handling, chaining operations.
4. Observables:
Purpose: Provide a stream of data over time. Subscribers can react to each emitted value and manage the lifetime of the observable.
Mechanism: Based on reactive programming principles. Use libraries like RxJS.
Use Cases: Real-time data streams, handling user events, building complex asynchronous workflows.
import { Observable } from 'rxjs';
const source = new Observable(observer => {
observer.next('Value 1');
observer.next('Value 2');
setTimeout(() => observer.complete(), 1000); // Simulate data stream
});
source.subscribe({
next: value => console.log(value),
complete: () => console.log('Stream completed')
});
In Essence:
Generators & Async Iterators: For working with sequences of values, either synchronous or asynchronous.
Promises: Representing the result of a single asynchronous operation.
Observables: Managing streams of data over time and reacting to events as they occur.
Last updated