Iterable and Iterator in ES6

ES6 / ES2015 introduced 2 new components :

1)iterables

2)iterators

What are iterables ?

Ans : It is a data structure that allows it’s data to be consumed.

 

example : If we have the array/Set/Map then with the help of iterables we can  able to consume the data.

 

How we   can achieve the iterator for the data source ?

We can achieve so by implementing a method (iterator) whose key is 

Symbol.iterator : This returns a  iterator() method.

Symbol is a new data type introduced in ES6

Why  we need iterables ?

Ans : Before ES6, in JavaScript if we have any data source, we need a diff approach to handle those data source.We are handling array/object/string in diff way. 

Note : In ES6 also we have introduced 2 new datasource 

a)Set

b)Map

 

Note ** : In JavaScript there must be some interface that all the data source can implement, so that all the data source can be consumed in similar manner.

Example :

Data source : Array , Object , Strings , Map , Set  etc

Interface :  Iterable

Consumers : Promise.all()  , Promise.race() , for ..of loop , spread operator , Destructuring , Array.from() , Map , Set Constructors

 

How to implement Iterable ?

To call a object iterable it needs to implement the iterable interface

Note : So , for an object (Array, Set , Map) to be iterable it needs a method that returns an iterator [an object]

That object should contain a method that returns the iterator

What is an iterator ?

It is a way to pull data from the data structure one at a time. It needs to implement the iterator interface

>next method : This method returns the IteratorResult Object

The IteratorResult object contains 2 items

a)done : true/false

If all data consumed for the object then it is true. But if all the data is not consumed for object then the done is false

b)value

Because array implements Iterable. So we can be able to invoke array through

for(let x of arr){

…..

}

 

Let us see how the arr object prototype contains Symbol.iterator

 let arr = [11, 34, 55, 876];

    for (let x of arr) {

        console.log("==>", x);

    }

 

    //let us call

    // arr.next(); Error

    /*

d3.html:15 Uncaught TypeError: arr.next is not a function

    */

 

    let itGun = arr[Symbol.iterator]();

    //arr[Symbol.iterator] is returning the reference of iterator method

    //so, we are calling it

    itGun.next();

    itGun.next();

 

Create custom iterator 

    let myGun = {

        [Symbol.iterator](){

return {

    start : 1,

    end : 10,

    next(){

if(this.start < this.end){

    return {

        done : false,

        value : this.start++

    }

}

else{

    return {

        done : true

    }

}

}}

   }}

for(x of myGun){

        console.log("==> ",x);

    }

let ii = myGun[Symbol.iterator]();

    console.log(ii.next().value);

    // console.log(ii.next());

    // console.log(ii.next());

 

Suppose we create a custom object without implementing the iterator then we can not :

1)for (x of obj) 

2)next() method

See below example for proof :

   let person = {

            first_name : "Mohan",

            last_name : "Sohan",

            age : 21

        }

        // for(x in person){

        //     console.log(x)

        // }

        /*

        for(y of person){

            console.log('=>',y)

        }

        console.log(person.next())

 

Uncaught TypeError: person is not iterable

Note : Sad , we can not be able to access the value through (for of operator) , net() method. But we can use of and next() for array , map ,set.

Reason is that all those array , set , map data source implements iterator

Let us now implement the iterator :

    let emp = {

        first_name: "Pablo",

        last_name: " Emilio",

        third_name: " Escobar ",

        fourth_name: " gavirio",

        age: 30,

        [Symbol.iterator]() {

            let self = this;

            let keyArr = [];

            for (let s1 in self) {

                keyArr.push(s1);

            }

            return {

                ind: -1,

                lt: keyArr.length - 1,

                next() {

                    if (this.ind <= this.lt) {

                        this.ind++;

                        return {

                            done: false,

                            value: self[keyArr[this.ind]]

                        }

                    }

                    else {

                        return {

                            done: true

                        }

                    }

                }

   }}

    }

for (item of emp) {

        console.log("==> ", item)

    }

console.log("\n *****Using next method ******* \n")

    let ii = emp[Symbol.iterator]();

    console.log(ii.next());

    console.log(ii.next());

    console.log(ii.next());

    console.log(ii.next());

    console.log(ii.next());

    console.log(ii.next());

 

Async iterator 

 var gun = {
        [Symbol.asyncIterator]() {
            return {
                start: 1,
                end: 10,
                async next() {
                    await new Promise(function (resolve, reject) {
                        setTimeout(function () {
                            if (this.start < this.end) {
                                resolve({
                                    value: this.start++,
                                    done: false
                                })
                            }
                            else {
                                resolve({
                                    done: true
                                });
                            }
                        }, 2000);
                    })
            }
            }
        }
    }
    async function show() {
            for await (let x of gun) {
        console.log(x);
    }
    }
    show();

Site Footer