Luca Del Puppo - Senior Software Developer
const array = ['a', 'b', 'c']
for (const item of array) {
console.log(item)
}
Output
a
b
c
for (const item of 'abc') {
console.log(item)
}
Output
a
b
c
const obj = {
a: 'a',
b: 'b',
c: 'c'
}
for (const item of obj) {
console.log(item)
}
Output: ⛔️ Uncaught TypeError: obj is not iterable
🤔
The for...of
statement executes a loop that operates on a sequence of values sourced from an iterable object. Iterable objects include instances of built-ins such as Array
, String
, TypedArray
, Map
, Set
, NodeList
(and other DOM collections), as well as the arguments
object, generators produced by generator functions, and user-defined iterables.
const a = ['a', 'b', 'c'];
console.log(...a)
Output
a
b
c
The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created.
Luca Del Puppo
Love sport: running, hiking
Love animals
interface Iterator {
next<T>(): {
done: boolean,
value: T
}
}
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
const iterator = {
next () {
return {
done: false,
value: "someValue"
}
}
}
interface Iterator {
next<T>(): {
done: boolean,
value: T
}
}
function range(start: number, end: number)
: Iterator<number> {
let n = start;
return {
next() {
if (n > end) {
return { done: true, value: null };
}
return { done: false, value: n++ };
}
};
};
function range(start: number, end: number)
: Iterable<number> {
return {
[Symbol.iterator]() {
let n = start;
return {
next() {
if (n > end) {
return { done: true, value: null };
}
return { done: false, value: n++ };
}
};
},
};
};
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
Well-know Symbols
const iterator =
range(1, 10)[Symbol.iterator]();
for (let result = iterator.next();
!result.done;
result = iterator.next()) {
console.log(result.value);
}
for (const value of range(1, 10)) {
console.log(value);
}
function range(start: number, end: number)
: Iterable<number> {
return {
[Symbol.iterator]() {
let n = start;
return {
next() {
if (n > end) return { done: true, value: null };
return { done: false, value: n++ };
},
return() {
return { done: true, value: null };
},
};
},
};
};
function* range(start: number, end: number)
: Iterable<number> {
let n = start;
while (n <= end) {
yield n++;
}
}
The Generator signature
The yield syntax
const iterator =
range(1, 10)[Symbol.iterator]();
for (let result = iterator.next();
!result.done;
result = iterator.next()) {
console.log(result.value);
}
for (const value of range(1, 10)) {
console.log(value);
}
how can I handle you?
const asyncIterator = {
async next () {
return {
done: false,
value: "someValue"
}
},
async return() {
return {
done: true,
value: undefined
}
}
}
interface AsyncIterator {
next<T>(): Promise<{
done: boolean,
value: T
}>,
return<T>(): Promise<{
done: boolean,
value: T
}>
}
const getUsers = (ids: number[]): AsyncIterable<User> => {
return {
[Symbol.asyncIterator]() {
let i = 0;
return {
async next() {
if (i === ids.length) {
return { done: true, value: null };
}
const data = await fetch(
`https://reqres.in/api/users/${ids[i++]}`
).then(res => res.json());
return { done: false, value: data };
},
async return() {
return { done: true, value: null };
},
};
},
};
};
for await (const user of getUsers([1, 2, 3, 4, 5])) {
console.log(user);
}
for await ... of
async function* getUsers(ids: number[]) {
for (const id of ids) {
const data = await
fetch(`https://reqres.in/api/users/${id}`)
.then(res =>
res.json()
);
yield data;
}
}
enable async
yield return
for await (const user of getUsers([1, 2, 3, 4, 5])) {
console.log(user);
}
I love csv
36KB
50KB
10KB
4GB
800MB
...
...
...
"1699553281266","0.1386636303377431"
"1699553281266","46.83486548448599"
"1699553281266","32.464374818037015"
"1699553281266","51.66273865612248"
"1699553281266","51.233009455984416"
"1699553281266","38.046865447500046"
"1699553281266","22.610913015578337"
...
...
...
Timestamp
Temperature
import {open} from 'node:fs/promises';
import Papa from 'papaparse';
...
const file = await open(filePath);
for await (const line of file.readLines()) {
const csvLine = Papa.parse(line)
const [timestamp,value] = csvLine.data[0]
const valueAsNumber = Number(value)
if (valueAsNumber > 50) {
console.log({ timestamp, valueAsNumber })
}
}
...
Image by catalyststuff on Freepik
Javascript Iterators & Generators
@puppo92
Luca Del Puppo
Puppo_92
@puppo