loading words...

Apr 17, 2019 22:06:22

Finally, a practical use case for JavaScript generators!My draft

by @swizecteller | 368 words | 🐣 | 116💌

Swizec Teller

Current day streak: 0🐣
Total posts: 116💌
Total words: 32303 (129 pages 📄)

JavaScript generators are amazing. A brilliant concept infinitely useful on paper.

They let you write infinite loops that terminate. Yield values from functions before they finish. Build lazy data structures. Lazy evaluation programming!

A functional programmer's wet dream. 😍

And I bet you've never used a JavaScript generator even once did you {{subscriber.first_name}}? Do you even know the syntax?

I bet you don't.

Turns out generators aren't very useful in practice. 😢

But yesterday, after years of knowing about generators, years of itching to use them, years of ... I FOUND A USE! A real world practical use-case where generators *actually* make your code better. 😱


We were adding automatic linking of twitter usernames to my [TechLetterApp](https://techletter.app) project. Find a piece of text, parse out `@username` instances, turn into links.

Easy right?

I thought so too. Complications around inserting complex nodes into an abstract syntax tree (AST) aside, parsing those usernames is hard to do elegantly.

Unless you use generators 😛

## Here's how we did it 👇

First, you create a regex that matches `@` followed by a series of word symbols.


const UserRegex = new RegExp(/@(\w+)/, "g");


Then you create a generator that runs this regex in a loop. Each `UserRegex.exec()` returns the next match.


function* getUsernames(string) {

let match = null;

do {

match = UserRegex.exec(string);

if (match) {

yield match;


} while (match);



We have a `*getUsernames` generator that takes a `string`. The asterisk notation changes a function to a generator.

Inside, a loop runs as long as `match` has a value. Assigned on each iteration as a `UserRegex.exec` call.

We `yield` existing values on every loop iteration. Last one will be `null` and we don't want to return those.

Yield is how you return values from generators. Notice that even after returning a value, the generator keeps running. That's the generator magic 🧙‍♀️

You can now find all usernames in a string with a loop.


const string = "this is a test with @swizec and @kyleshevlin, maybe @lukeed05"

for (const username of getUsernames(string)) {




That outputs


["@swizec", "swizec"]

["@kyleshevlin", "kyleshevlin"]

["@lukeed05", "lukeed05"]



Here's a CodeSandbox you can play with




Originally published at twitter.com

  • 1

    @swizecteller -- nice going to rewrite this and practice- @baz - you could use this

    Brian Ball avatar Brian Ball | Apr 17, 2019 23:55:37
contact: email - twitter / Terms / Privacy