from() - Converteer Arrays/Promises
from() is een Creation Function die Observables genereert van arrays, Promises, iterables en Observable-achtige objecten.
Overzicht
from() converteert bestaande datastructuren (arrays, Promises, iterables, etc.) naar Observable streams. Vooral handig voor het integreren van async operaties (Promises) in de RxJS-wereld.
Signature:
function from<T>(input: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T>Officiële Documentatie: 📘 RxJS Official: from()
Basisgebruik
from() accepteert verschillende inputtypes.
import { from } from 'rxjs';
// Van array maken
const array$ = from([1, 2, 3]);
array$.subscribe({
next: value => console.log('Array waarde:', value),
complete: () => console.log('Array compleet')
});
// Van Promise maken
const promise$ = from(Promise.resolve('Promise resultaat'));
promise$.subscribe({
next: value => console.log('Promise resultaat:', value),
complete: () => console.log('Promise compleet')
});
// Van iterable maken
const iterable$ = from(new Set([1, 2, 3]));
iterable$.subscribe({
next: value => console.log('Iterable waarde:', value),
complete: () => console.log('Iterable compleet')
});
// Output:
// Array waarde: 1
// Array waarde: 2
// Array waarde: 3
// Array compleet
// Iterable waarde: 1
// Iterable waarde: 2
// Iterable waarde: 3
// Iterable compleet
// Promise resultaat: Promise resultaat
// Promise compleetBelangrijke Kenmerken
1. Emit Array-elementen Afzonderlijk
from() emit bij arrays elk element afzonderlijk in volgorde.
import { from } from 'rxjs';
from([10, 20, 30]).subscribe(value => console.log(value));
// Output:
// 10
// 20
// 30IMPORTANT
Verschil met of():
of([1, 2, 3])→ Emit array zelf als één waardefrom([1, 2, 3])→ Emit elementen1,2,3afzonderlijk
2. Automatische Promise Verwerking
Bij Promises wordt de resolved waarde geëmit en direct compleet.
import { from } from 'rxjs';
const fetchData = (): Promise<string> => {
return new Promise(resolve => {
setTimeout(() => resolve('Data ophalen compleet'), 1000);
});
};
from(fetchData()).subscribe({
next: value => console.log(value),
complete: () => console.log('Compleet')
});
// Na 1 seconde output:
// Data ophalen compleet
// CompleetWARNING
Bij Promise rejection emit de Observable een error.
import { from } from "rxjs";
from(Promise.reject('Fout')).subscribe({
error: err => console.error('Fout opgetreden:', err)
});3. Iterable Support
Ondersteunt iterables zoals Set, Map, Generator, etc.
import { from } from 'rxjs';
// Set
from(new Set(['A', 'B', 'C'])).subscribe(console.log);
// Output: A, B, C
// Map (key-value pairs)
from(new Map([['key1', 'value1'], ['key2', 'value2']])).subscribe(console.log);
// Output: ['key1', 'value1'], ['key2', 'value2']
// Generator
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
from(numberGenerator()).subscribe(console.log);
// Output: 1, 2, 34. Cold Observable
from() is een Cold Observable. Bij elke subscription start een onafhankelijke uitvoering.
import { from } from 'rxjs';
const numbers$ = from([1, 2, 3]);
numbers$.subscribe(val => console.log('Subscriber A:', val));
numbers$.subscribe(val => console.log('Subscriber B:', val));
// Elke subscriber verwerkt de array onafhankelijk
// Output:
// Subscriber A: 1
// Subscriber A: 2
// Subscriber A: 3
// Subscriber B: 1
// Subscriber B: 2
// Subscriber B: 3NOTE
Cold Observable Kenmerken
- Bij elke subscription start een onafhankelijke uitvoering
- Elke subscriber ontvangt zijn eigen datastream
- Ook bij Promises wordt bij elke subscription opnieuw geëvalueerd
Zie Cold en Hot Observables voor meer details.
Verschil tussen from() en of()
Het belangrijkste verschil is hoe arrays worden behandeld.
import { from, of } from 'rxjs';
const array = [1, 2, 3];
// of() - Emit array als één waarde
of(array).subscribe(value => {
console.log('of():', value); // [1, 2, 3]
});
// from() - Emit elk array-element afzonderlijk
from(array).subscribe(value => {
console.log('from():', value); // 1, 2, 3
});| Creation Function | Array behandeling | Gebruik |
|---|---|---|
of([1, 2, 3]) | Emit array zelf | Array als data gebruiken |
from([1, 2, 3]) | Emit elk element afzonderlijk | Array-elementen één voor één verwerken |
Praktische Gebruikssituaties
1. API Aanroepen Streamen
Stream Promise-gebaseerde HTTP clients zoals Fetch API of axios.
import { from, Observable, of } from 'rxjs';
import { catchError } from 'rxjs';
interface User {
id: number;
name: string;
email: string;
}
function fetchUser(id: number): Observable<User> {
return from(
fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
.then(response => response.json())
).pipe(
catchError(error => {
console.error('API Fout:', error);
return of({ id: 0, name: 'Unknown', email: '' });
})
);
}
fetchUser(1).subscribe(user => console.log('User:', user));2. Array-elementen Sequentieel Verwerken
Voer async operaties sequentieel uit op elk array-element.
import { from } from 'rxjs';
import { concatMap, delay } from 'rxjs';
const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3'
];
from(urls).pipe(
concatMap(url =>
from(fetch(url).then(res => res.json())).pipe(
delay(500) // Rate limiting
)
)
).subscribe(data => console.log('Opgehaald:', data));3. Async Iterator Verwerking
Ondersteunt ook async iterators (async generators).
import { from } from 'rxjs';
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
from(asyncGenerator()).subscribe(value => console.log(value));
// Output: 1, 2, 34. Event Emitter Integratie
Stream Node.js EventEmitter of custom event systemen.
import { from } from 'rxjs';
// Iterable custom object
class DataSource {
*[Symbol.iterator]() {
yield 'Data A';
yield 'Data B';
yield 'Data C';
}
}
from(new DataSource()).subscribe(console.log);
// Output: Data A, Data B, Data CGebruik in Pipelines
from() is handig als startpunt voor pipeline verwerking van bestaande data.
import { from } from 'rxjs';
import { map, filter, reduce } from 'rxjs';
interface Product {
id: number;
name: string;
price: number;
}
const products: Product[] = [
{ id: 1, name: 'Product A', price: 1000 },
{ id: 2, name: 'Product B', price: 2000 },
{ id: 3, name: 'Product C', price: 500 }
];
from(products).pipe(
filter(product => product.price >= 1000),
map(product => product.price),
reduce((sum, price) => sum + price, 0)
).subscribe(total => console.log('Totaal bedrag:', total));
// Output: Totaal bedrag: 3000Veelgemaakte Fouten
1. Verkeerde Promise Executie Timing
// ❌ Fout - Promise wordt uitgevoerd bij creatie
const promise = fetch('https://jsonplaceholder.typicode.com/posts/1'); // Al gestart
from(promise).subscribe(console.log); // Niet bij subscription
// ✅ Correct - Gebruik defer() voor uitvoering bij subscription
import { defer, from } from 'rxjs';
const deferred$ = defer(() =>
from(fetch('https://jsonplaceholder.typicode.com/posts/1'))
);
deferred$.subscribe(console.log); // Uitgevoerd bij subscriptionWARNING
Promises zijn niet lazy
Promises starten uitvoering bij creatie. from(promise) wrapt alleen een al lopende Promise. Gebruik defer(() => from(promise)) voor uitvoering bij subscription.
2. Array en of() Verwarren
import { from, map, of } from "rxjs";
// ❌ Niet de bedoeling - Hele array wordt geëmit
of([1, 2, 3]).pipe(
map(n => n * 2)
).subscribe(console.log);
// Output: [1, 2, 3] (array zelf)
// ✅ Correct - Elk element afzonderlijk verwerken
from([1, 2, 3]).pipe(
map(n => n * 2)
).subscribe(console.log);
// Output: 2, 4, 6Prestatieoverwegingen
from() prestaties variëren per inputtype.
TIP
Optimalisatie Tips:
- Bij grote datasets (duizenden elementen), beperk parallellisme bij
concatMapofmergeMap. - Overweeg
forkJoinofcombineLatestbij Promise arrays.
import { from } from 'rxjs';
import { mergeMap } from 'rxjs';
const urls = [...Array(100)].map((_, i) => `https://jsonplaceholder.typicode.com/posts/${i + 1}`);
from(urls).pipe(
mergeMap(
url => from(fetch(url).then(res => res.json())),
5 // Beperk parallelle uitvoering tot 5
)
).subscribe(data => console.log(data));Gerelateerde Creation Functions
| Function | Verschil | Gebruik |
|---|---|---|
| of() | Emit argumenten in volgorde | Waarden direct emittende |
| fromEvent() | Stream events | DOM events of EventEmitter |
| defer() | Lazy creatie bij subscription | Lazy Promise executie |
| ajax() | HTTP-specifiek | RxJS HTTP requests |
Samenvatting
from()genereert Observables van arrays, Promises, iterables- Emit array-elementen afzonderlijk (verschilt van
of()) - Verwerkt Promises automatisch en emit resultaat
- Ideaal voor integratie van async operaties in RxJS
- Let op: Promises starten bij creatie (gebruik
defer()voor lazy executie)