Await Your Loops
Tags: javascript, coding
Published: 2017-11-13 23:54:48

---
title: Await Your Loops
published: true
description: Asynchronous iteration in JavaScript
tags: javascript, coding
cover_image: https://thepracticaldev.s3.amazonaws.com/i/az53zujtgn3yp3niunf9.jpg
---
_[Cover image by Dakota Ray on Flickr](https://www.flickr.com/photos/dakotaray/)_


If you read stuff about JavaScript lately, you probably already know that it gets new features every now and then. One of those are __Asynchronous Iterations__.

You probably already know about iterables and async/await, but if not don't worry, I'll update you first.

## Iterables

[Iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) are objects that have a method in the `Symbol.iterator` field that returns an object with a `next()` method. This can be used to get all iterable values of that object.

In case of an array, an object which is JS-built-in, it looks like this:

```javascript
const a = [1, 2, 3];
const iteratorOfA = a[Symbol.iterator]();

iteratorOfA.next(); // { value: 1, done: false }
iteratorOfA.next(); // { value: 2, done: false }
iteratorOfA.next(); // { value: 3, done: false }
iteratorOfA.next(); // { value: undefined, done: true}

```

The nice thing is, you can use it in a for-in-loop, without all the extra syntax.

```javascript
const a = [1, 2, 3];
for(let i in a) console.log(i); 

```

But yes, this isn't too exiting, basic JavaScript stuff.

The cool part is, that you can write your own iterables:


```javascript
const iterable = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  [Symbol.iterator]: function() {
    const keys = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        if (i == keys.length) return {value: null, done: true};
        return {
          value: [keys[i], this[keys[i++]]],
          done: false
        };
      }
    }
  }
};

for(let item of iterable) console.log(item);
```

`Object.keys()` only returns the non-symbol keys as an array, so `Symbol.iterator` won't show up in it.

Now, when the next method of that returned object is called, I return a new key and value pair as an array. When I don't find any more pairs, I return an object with `done: true` and tell the caller that I'm finished.

As you can see in the end, this new object can be used like an array in a for-in-loop.

## Async/Await

A not-so-basic JavaScript feature, which is rather recent are asynchronous functions, or [async/await](https://dev.to/kayis/javascript-awaits).

Essentially it adds syntax sugar to promises.

Without async/await it would look like that:

```javascript
function load(url) {
  return fetch(url)
  .then(response => response.json())
  .(json => json.data);
}
```

And with you get to write code that _looks_ synchronous again:

```javascript
async function load(url) {
  const response = await fetch(url);
  const json = await response.json();
  return json.data;
}
```

## Asynchronous Iterations

As you can probably imagine, there are quite some asynchronous operations that won't be done with just one promise.

But you can't simply write something like that:

```javascript
function processRows(filePath) {
  for(let row of getRow(filePath)) {
    ...
  }
}
```
Because the `getRow()` call would hit the file-system, which is an asynchronous operation. You would have to read the whole file, before you could get the single rows for processing.

Or it could be a server call that ends up being paginated and you would have to send multiple of them to get all pages.

But now there is an [proposal](https://github.com/tc39/proposal-async-iteration) for that too!

Instead of using `Symbol.iterator` and using a next-method that returns your values, you use `Symbol.asyncIterator` and use a next-method that returns promises of those values.

```javascript
const asyncIterable = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  [Symbol.asyncIterator]: function() {
    const keys = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        if (i == keys.length) return Promise.resolve({value: null, done: true});
        return Promise.resolve({
          value: [keys[i], this[keys[i++]]],
          done: false
        });
      }
    }
  }
};

async function process() { 
  for await (let item of asyncIterable) console.log(item);
}

process();

```
And we're back to code that can be sprinkled with try/catch and all the other nice synchronous features.

As you can see, you can simply return a promise that resolves to an object with `done: true` if your iterable data is finished. Like, when the server doesn't return anything anymore.

In that example the data is in-memory, but could come from anywhere now.

## Conclusion

Asynchronous iterables are another step in making async/await syntax and promises more ingrained into JavaScript. They ease the work of writing asynchronous code by making it look more and more synchronous.

An alternative, which I mentioned in other posts too, are [observables](https://github.com/tc39/proposal-observable) like provided by [RxJS](https://github.com/ReactiveX/rxjs).