Skip to content

Instantly share code, notes, and snippets.

@rishabhgupta
Last active July 12, 2018 04:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rishabhgupta/c06e21d136c22fd50d6261e69cb7e200 to your computer and use it in GitHub Desktop.
Save rishabhgupta/c06e21d136c22fd50d6261e69cb7e200 to your computer and use it in GitHub Desktop.
symbols Iterators and generators
let emailIds = ['a@gmail.com','b@gmail.com','c@gmail.com']
console.log( emailIds[Symbol.iterator] ); // Property name is a symbol
// OUTPUT: function
// Lets store this iterator
let emailIter = emailIds[Symbol.iterator]();
console.log(emailIter.next());
// OUTPUT {done: false, value: 'a@gmail.com'}
emailIter.next() // b@gmail.com
// The last element
console.log(emailIter.next());
// OUTPUT {done: false, value: 'c@gmail.com'}
// Lets call it one more time
console.log(emailIter.next());
// OUTPUT {done: true, value: undefined}
// Iterator in exhausted.
async function asyncfn() {
var one = await Promise.resolve(1);
var two = await Promise.resolve(2);
console.log(one, two);
}
asyncfn();
// 1 2
let asyncIter = {
[Symbol.asyncIterator]: async function *asyncGenerator(){
let promises = [asyncFn, asyncFn2];
while(promises.length){
let prom = promises.shift()
yield await prom();
}
yield await Promise.resolve({value: undefined, done:true})
}
};
(async function() {
// it waits for each item to resolve
// before moving to the next()
for await (const item of asyncIter) {
console.log(item);
// 1 2
}
})();
function asyncFn() {
let prom = new Promise(function(resolve, reject){
setTimeout(function(){
resolve({value:1, done:false}); // Note return format of the promise
},2000);
});
return prom;
}
function asyncFn2() {
let prom = new Promise(function(resolve, reject){
setTimeout(function(){
resolve({value:3, done:false});
},3000);
});
return prom;
}
function asynIterator(){
var promises = [asyncFn, asyncFn2];
var iter = 0;
return {
next: function () {
if (iter < promises.length){
const temp = iter;
iter ++;
return promises[temp](); // Return Promise
} else {
// Exhaust the iterator
return Promise.resolve({
value: undefined,
done: true
})
}
}
}
}
var iterator = asynIterator(); // Iterator
(async function() {
await iterator.next().then(console.log); // { value: 1, done: false }
await iterator.next().then(console.log); // { value: 2, done: false }
await iterator.next().then(console.log); // { done: true }
})();
// Instead of creating a normal iterator
// var iterator = asycnIterator();
// Create a async iterator
var asyncIter = {
[Symbol.asyncIterator]: asyncIterator
};
// Then we can use for-wait-of loop
(async function () {
for await (const item of asyncIterator) {
console.log(item);
}
}());
// 1
// 2
for(let id of studentIdGenerator()){
console.log(id);
}
//OUTPUT:
// 10301
// 10302
function *studentIdGenerator(){
yield 103001;
yield 103002;
}
let studentIdIterator = studentIdGenerator();
console.log(studentIdIterator.next())
// OUTPUT: {value: 103001, done: false}
studentIdIterator.next() // {value: 103002, done: false}
console.log(studentIdIterator.next())
// OUTPUT: {value: undefined, done: true}
function *returnGenerator(){
yield 1;
yield 3;
}
let iter = returnGenerator();
console.log(iter.next()); // OUTPUT: {value: 1, done: false}
console.log(iter.return(2)); // OUTPUT {value: 2, done: true}
console.log(iter.next()); // OUTPUT: {value: undefined, done: true}
function *throwGenerator(){
try {
yield 1
yield 2
} catch (e){
console.log(e);
}
}
let iter = throwGenerator();
console.log(iter.next()); // OUTPUT: {value: 1, done: false}
console.log(iter.throw('exception')) // OUTPUT: {value: undefined, done: true}
console.log(iter.next()); // OUTPUT: {value: undefined, done: true}
let asyncIter = {
[Symbol.asyncIterator]: async function *asyncGenerator(){
let promises = [Promise.resolve(1), Promise.resolve(2)];
while(promises.length){
let prom = promises.shift()
yield await prom();
}
yield await Promise.resolve({value: undefined, done:true})
}
};
let studentId = {
[Symbol.iterator]() {
let id = 10300;
return {
next(){
let value = id > 10305 ? undefined : id++;
let done = !value; // value is undefined means we have reached our limit
// Setting done to true will exit the iteration.
return {value, done};
}
};
}
};
for(let id of studentId){
console.log(id);
}
// OUTPUT
//10300
//10301
//10302
//10303
//10304
//10305
let PageNumer = {
[Symbol.iterator]() {
let nextPageNum = 1;
return {
next(){
return {
value: nextPageNum++,
done: false
};
}
};
}
};
let PageNumerIter = PageNumer[Symbol.iterator]();
for (let page of PageNumerIter){
if (page > 2) break;
console.log(page);
}
// OUTPUT:
// 1
// 2
let author = {
name: 'Cipherhack',
[Symbol.for('post')]: 'New Post'
};
let value = author[Symbol.for('post')];
console.log(value);
// New Post
// Can we get the unique id as the key of 'New Post' is a symbol ?
console.log( Object.getOwnPropertyNames(author) );
// OUTPUT: ['title'] :( Symbols get ignored.
// Let try getting all symbols properties on this object
console.log( Object.getOwnPropertySymbols(author) );
// OUTPUT [Symbol(article)]
let symb = Symbol.for('Sample Symbol');
let description = Symbol.keyFor(symb);
console.log(description);
// OUTPUT: Sample Symbol
let getSymb1 = Symbol.for('Sample Register');
// As this symbol does not exist in the registry, it will be created
let getSymb2 = Symbol.for('Sample Register');
// Symbol will look up the registry and return the same symbol getSymb1
console.log(getSymb2 === getSymb1);
// OUTPUT: true
let symb1 = Symbol('Sample Symbol');
let symb2 = Symbol('Sample Symbol');
console.log(symb1 === symb2);
// OUTPUT: false
// Lets start by create a new symbol and assiging it to a variable
let symb = Symbol('Sample Symbol');
console.log(typeof symb);
// OUTPUT: symbol
// Lets try and convert it into a string, may be we get to know the unique id
console.log(symb.toString());
// OUTPUT: Symbol(Sample Symbol)
function *emailIdGenerator(){
yield ['a@gmail.com','b@gmail.com', 'c@gmail.com']
}
let iter = idGenerator();
console.log(iter.next())
// OUTPUT: {done: false, value: ["a@gmail.com", "b@gmail.com", "c@gmail.com"]}
function *idGenerator(){
let num = yield; // Note no value has been specified for yield
console.log(`Num is ${num}`);
}
let iter = idGenerator();
console.log(iter.next());
// OUTPUT: {value: undefined, done: false}
console.log(iter.next(20));
// OUTPUT: Number is 90
// OUTPUT: {value: undefined, done: true}
function *idGenerator(){
yield; // Note no value has been specified
}
let iter = idGenerator();
console.log(iter.next());
// OUTPUT {value: undefined, done: false}
function *studentIdGenerator(){
yield 1;
yield* [2,3]
yield 4;
}
let iter = studentIdGenerator();
console.log(iter.next()); //OUTPUT: {value: 1, done: false}
console.log(iter.next()); //OUTPUT: {value: 2, done: false}
// Note: first element of the array not entire array
console.log(iter.next()); // OUTPUT: {value: 3, done: false}
console.log(iter.next()); // OUTPUT: {value: 4, done: false}
// Note: As the arrays iterator has exhausted the generators iterator takes over
console.log(iter.next()); // OUTPUT: {value: undefined, done: true}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment