-
Notifications
You must be signed in to change notification settings - Fork 0
32 Generators
Biswajit Sundara edited this page Aug 18, 2023
·
1 revision
Generator is simply a function that can be paused.
- In other words a function that returns an object on which we can call
next(). - Every invocation of next() will return an object of shape
{ value: Any, done: true|false}
Syntax
function* name(){
const variable = yield value;
}- We will notice, its returning object each time next() is called.
- And the Object is having two properties: value & true | false.
- The last line prints true, because that time the function has completed generating values and there is nothing more to return.
const getNumbers = function* (){
yield 1;
yield "hello";
yield "true";
yield {name:"Biswajit"};
return "i am done";
}
const numberGen = getNumbers();
console.log(numberGen.next());
console.log(numberGen.next());
console.log(numberGen.next());
console.log(numberGen.next());
console.log(numberGen.next());
------------- OUT PUT ---------------
{ value: 1, done: false }
{ value: 'hello', done: false }
{ value: 'true', done: false }
{ value: { name: 'Biswajit' }, done: false }
{ value: undefined, done: true }We can directly access the values this way.
console.log(numberGen.next().value);
console.log(numberGen.next().value);
console.log(numberGen.next().value);
console.log(JSON.stringify(numberGen.next().value));
console.log(numberGen.next().value);const getNumbers = function* (numbers){
for(let i=0;i<numbers.length;i++){
yield numbers[i];
}
}
const getNumbersGen = getNumbers([1,2,3,4,5]);
const interval = setInterval(()=>{
const next = getNumbersGen.next();
if(next.done){
console.log("This generator is done");
clearInterval(interval);
}
else{
const number = next.value;
console.log(number);
}
},1000);
---------------- OUTPUT -------------------
1
2
3
4
5
This generator is doneThis will make codes more cleaner and easy to debug.
A. Without Generator
Problems with this approach is look at the layers. If we have to catch errors then we will have to write catch block for all the promises which will make it more ugly.
const getRandomUsers = ((numberOfUsers)=>{
const fetchUsers = fetch(`https://randomuser.me/api/?results=${numberOfUsers}`);
console.log(fetchUsers);
fetchUsers.then((response)=>{
response.json().then((randomusers)=>{
console.log(JSON.stringify(randomusers));
console.log(JSON.stringify(randomusers.results.length));
randomusers.results.array.forEach(user => {
const {gender, email} = user;
console.log(`${gender} ${email}`);
});
})
})
})
getRandomUsers(5);B. Coroutine
For this we will have to install 'bluebird' library. Here we are using promises and generators together and it makes the code much cleaner and to debug easily.
import { coroutine as co } from 'bluebird';
const getRandomUsers = co(function* (numberOfUsers) {
const fetchUsers = yield fetch(`https://randomuser.me/api/?results=${numberOfUsers}`);
const response = yield fetchUsers.json();
return response;
});
getRandomUsers(10).then((randomusers) => {
randomusers.results.array.forEach(user => {
const { gender, email } = user;
console.log(`${gender} ${email}`);
});
}).catch((err)=>{
console.log(err);
})