- Iterator and Generator
- For of loop
- Async Iterator and Generator
- Github Collaboration
- Project Requirements
We use iterator because we cannot pause a loop. When a loop starts it will not stop until the execution of last element. Let's look the below example:
const arr = [1, 2, 3, 4];
let index = 0;
function next() {
return arr[index++];
}
console.log(next()); // 1
console.log(next()); // 2
console.log(next()); // 3
console.log(next()); // 4
console.log(next()); // undefined
In iterator if there is no value it returns simply undefined
.
const channel = 'Stack';
const channelIterator = channel[Symbol.iterator]();
console.log(channelIterator.next()); // { value: 'S', done: false }
console.log(channelIterator.next()); // { value: 't', done: false }
console.log(channelIterator.next()); // { value: 'a', done: false }
console.log(channelIterator.next()); // { value: 'c', done: false }
console.log(channelIterator.next()); // { value: 'k', done: false }
console.log(channelIterator.next()); // { value: undefined, done: true }
console.log(channelIterator.next()); // { value: undefined, done: true }
const range = {
start: 0,
stop: 100,
step: 5,
};
range[Symbol.iterator] = function () {
let current = this.start;
const stop = this.stop;
const step = this.step;
return {
next() {
const o = {
value: current,
done: current > stop,
};
current += step;
return o;
},
};
};
for (let v of range) {
console.log(v);
}
Generator is used to create an iterator more easily. Generator always returns an iterator. To create a generator
function we need to add an asterisk(*) after function
keyword like this function*
. For example:
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const iterator = myGenerator();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
function* range(start = 0, stop = 100, step = 5) {
for (let i = start; i <= stop; i += step) {
yield i;
}
}
// const rangeIt = range(1, 10, 3);
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
// console.log(rangeIt.next());
for (let v of range()) {
console.log(v);
}
function* generateId() {
let index = 1;
while (true) {
yield index++;
}
}
const generateUserId = generateId();
const generateProductId = generateId();
console.log('User', generateUserId.next().value);
console.log('User', generateUserId.next().value);
console.log('User', generateUserId.next().value);
console.log('Product', generateProductId.next().value);
console.log('Product', generateProductId.next().value);
console.log('Product', generateProductId.next().value);
console.log('Product', generateProductId.next().value);
console.log('Product', generateProductId.next().value);
console.log('Product', generateProductId.next().value);
const channel = 'Stack';
const channelIterator = channel[Symbol.iterator]();
for (let v of channel) {
console.log(v); // S t a c k
}
const axios = require('axios').default;
async function getUsers() {
const url = 'https://jsonplaceholder.typicode.com/users';
const { data: users } = await axios.get(url);
return users;
}
async function* getPostsByUser(users) {
const url = 'https://jsonplaceholder.typicode.com/posts';
for (let i = 0; i < users.length; i++) {
const { data: posts } = await axios.get(`${url}?userId=${users[i].id}`);
yield posts;
}
}
getUsers()
.then(async (users) => {
// const userIterator = await getPostsByUser(users);
// await userIterator.next();
// await userIterator.next();
// console.log((await userIterator.next()).value);
for await (let v of getPostsByUser(users)) {
console.log(v.map((d) => d.title));
}
})
.catch((e) => {
console.log(e);
});
We can write the above program as below:
const axios = require('axios').default;
async function getUsers() {
const url = 'https://jsonplaceholder.typicode.com/users';
const { data: users } = await axios.get(url);
return users.map((user) =>
axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`)
);
}
(async () => {
const users = await getUsers();
for await (let v of users) {
console.log(v.data.map((post) => post.title));
}
})();
We need an attendance system. Students can create their own profile. Admin can see list of students and their attendances. Admin can enable and disable attend button. Also this button can be disabled based on a timer. Each time admin enable attend button, students can participate for only once. Each day, student will have a time sheet of attendance.
Student can see their own time logs and attend button when enable.
- Iterators and generators - JavaScript | MDN
- JavaScript iterators and generators: A complete guide - LogRocket Blog
- for await...of - JavaScript | MDN
- JavaScript async iterators
- Class Overview