• Stars
    star
    506
  • Rank 86,863 (Top 2 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created about 8 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⌛ Use async functions in your JavaScript today with speed and simplicity.

async-to-gen

npm Build Status

Turn your JavaScript with async functions into ES6 generators so they can be used in modern browsers or in node.js (v0.12 or newer).

Async functions are an exciting new proposed addition to JavaScript. The v8 team is hard at work getting it right, which means it could appear in future versions of node.js. However if you're impatient like me, then you probably just can't wait to get rid of your promise triangles and callback hell.

You can use Babel to accomplish this, but async-to-gen is a faster, simpler, zero-configuration alternative with minimal dependencies for super-fast npm install and transform time.

Also, async-to-gen provides support for async generators which return Async Iterators, a great syntax and primitive for producing and operating on streams of data.

Get Started!

Use the command line:

npm install --global async-to-gen
async-to-gen --help
async-to-gen input.js > output.js

# source maps!
async-to-gen input.js --sourcemaps inline > output.js

Or the JavaScript API:

npm install async-to-gen
var asyncToGen = require('async-to-gen');
var fs = require('fs');

var input = fs.readFileSync('input.js', 'utf8');
var output = asyncToGen(input).toString();
fs.writeFileSync('output.js', output);

// source maps!
var map = asyncToGen(input).generateMap();
fs.writeFileSync('output.js.map', JSON.stringify(output));

Use async-node

Wherever you use node you can substitute async-node and have a super fast async functions aware evaluator or REPL.

$ async-node
> async function answer() {
... return await 42
... }
undefined
> promise = answer()
Promise { <pending> }
> promise.then(console.log)
Promise { <pending> }
42

Use the require hook

Using the require hook allows you to automatically compile files on the fly when requiring in node, useful during development:

require('async-to-gen/register')
require('./some-module-with-async-functions')

You can also provide options to the require hook:

// Disable inline source maps for use with development tools.
require('async-to-gen/register')({ sourceMaps: false })

Use options to define exactly which files to includes or excludes with regular expressions. All files are included by default except those found in the node_modules folder, which is excluded by default. Pass excludes: null to not exclude any files.

require('async-to-gen/register')({ includes: /\/custom_path\// })

The require hook also offers the ability to set options and revert the require hook:

const asyncHook = require('async-to-gen/register')
// Similar to example above.
asyncHook.setOptions({ includes: /\/custom_path\// })
// Reverts the require hook.
asyncHook.revert()

Don't use the require hook in packages distributed on NPM

As always, don't forget to use async-to-gen to compile files before distributing your code on npm, as using the require hook affects the whole runtime and not just your module and may hurt the runtime performance of code that includes it.

Use in Build Systems:

Rollup: rollup-plugin-async

Common Usage

Async I/O

Async functions are great for writing asynchronous code that looks synchronous, and that's perfect for writing code that needs to perform async I/O operations.

One of the original motivations for Node.js was non-blocking I/O, perfect! However its core libraries do not yet support Promises, nor do many popular libraries written for Node 😭.

Do not fret, we can fix this with promisify-node!

const promisify = require('promisify-node');
const fs = promisify('fs');

async function emojify(filePath) {
  const contents = await fs.readFile(filePath, 'utf8')
  const edited = contents.replace(/:\)/g, '😉')
  await fs.writeFile(filePath, edited, 'utf8')
}

Mocha

Writing tests in mocha? Async functions are super handy for testing any code using promises and already work out of the box! To enable async functions in mocha include the require hook when you run your tests:

mocha --require async-to-gen/register test.js

Then in your tests, use async functions in your it clauses:

describe('My Promising Module', () => {

  it('promises to give a value', async () => {
    expect(await myFunction('input')).to.equal('output')
  })

})

Testing your express app? Try supertest and async functions:

const express = require('express')
const request = require('supertest')

const app = express()
app.get('/foo', (req, res) => res.send('bar'))

describe('My express app', () => {

  it('loads foo', async () => {
    const response = await request(app).get('/foo')
    expect(response.body).to.equal('bar')
  })

})

Jest

Writing tests in Jest? Use the scriptPreprocessor entry in your jest configuration in package.json:

{
  "name": "my-project",
  "jest": {
    "transform": {
      "^.+\\.js$": "async-to-gen"
    }
  },
  "devDependencies": {
    "async-to-gen": "*"
  }
}

Scripts

Have interactive scripts that require lots of input from the user? Async functions make writing those much easier! Check out interactive-script.

npm install interactive-script

Then write your script:

const interactive = require('interactive-script')
interactive(async (say, ask) => {
  say('What is your favorite number?')
  let num;
  do {
    num = Math.ceil(Math.random() * 100)
  } while (!await ask(`Is it ${num}? `, 'yN'))
  say(`Great, I think ${num} is a fine number.`)
})

And run it with async-node:

async-node myScript.js

Streams

Streaming data can be a challenging thing to get right. While Observables have provided a great library for streamed data, Async Generators provides language-level support for this concept!

Consider subscribing to a web socket within an program using async functions:

async function* stockTickerInEuro(symbol) {
  var socket = await openWebSocket('ws://stocks.com/' + symbol)
  try {
    for await (var usd of socket) {
      var euro = usd * await loadExchangeRateUSD2EUR()
      yield euro
    }
  } finally {
    closeWebSocket(socket)
  }
}

Then calling this function produces an Async Iterator (an Iterator of Promises) of stock ticker values.

var ticker = stockTickerInEuro('AAPL')
ticker.next().then(step => console.log(step.value))

Or use for-await-of loops within another async function:

async function bloombergTerminal() {
  for await (var price of stockTickerInEuro('AAPL')) {
    console.log(price)
  }
}

Dead-Simple Transforms

When async-to-gen transforms async functions, it makes as few edits as possible, and does not affect the location of lines in a file, leading to easier to understand stack traces when debugging.

It also includes a very small conversion function at the bottom of the file. How small? 204 chars for async functions and 533 chars for async generators.

Before:

async function foo() {
  return await x
}

After:

function foo() {return __async(function*(){
  return yield x
}())}

function __async(g){/* small helper function */}

Using with Babel

Don't bother using both! If you're already using Babel (maybe you need JSX, other proposed features, or are supporting older versions of Node) then you might be excited to hear that using babel-preset-es2017 in your .babelrc will provide support for async functions!

Babel is an amazing tool that you should consider using, however async-to-gen intentionally makes some different choices to provide a different set of trade-offs. Babel is general-purpose and supports a wider set of features but requires some configuration and more dependencies and those features may cost build performance or output code quality. async-to-gen can only do one thing, but that simplicity lends itself towards faster builds and cleaner output.

Ultimately, if you only need to add async function support you should try async-to-gen but if you need more features then you should use Babel.

More Repositories

1

testcheck-js

Generative testing for JavaScript
JavaScript
1,184
star
2

react-loops

React Loops works with React Hooks as part of the React Velcro Architecture
JavaScript
1,166
star
3

iterall

🌻 Minimal zero-dependency utilities for using Iterables in all JavaScript environments.
JavaScript
815
star
4

spec-md

📖 Additions to Markdown for writing specification documents
HTML
380
star
5

streamgraph

Processing applet which creates the images seen in the Streamgraph paper
Java
281
star
6

ecmascript-more-export-from

Proposal: add more export-from statements in ES7
153
star
7

mesh

Processing library for creating point meshes.
Java
97
star
8

rollup-plugin-flow

Rollup plugin for removing Flow type annotations.
JavaScript
80
star
9

4000

63
star
10

cocoa-oauth2

Cocoa library for handling oauth2
59
star
11

til

Today I Learned
JavaScript
55
star
12

interactive-script

Easy to write interactive scripts
JavaScript
52
star
13

ecmascript-iterator-hof

Higher Order Functions on Iterators
JavaScript
42
star
14

rollup-plugin-async

Transforms Async functions to generator functions before bundling.
JavaScript
40
star
15

ecmascript-reverse-iterable

ReverseIterable Interface Spec Proposal
JavaScript
30
star
16

keyboard

My keyboard config
30
star
17

anyconnect-dark

Dark OSX menu bar assets for Cisco AnyConnect VPN.
24
star
18

mocha-check

Generative property testing for Mocha
17
star
19

bigtype

💥 Type big stuff
HTML
17
star
20

huron.wedding

Our wedding site
HTML
16
star
21

centerclock

A generative abstract clock.
JavaScript
13
star
22

fb-notify

Objective-C
12
star
23

grunt-jest

Grunt task for running jest tests.
JavaScript
12
star
24

respectify

Replaces the term 'politically correct' with 'respectful of other people' because it makes you oddly happy.
JavaScript
12
star
25

jasmine-check

Generative property testing for Jasmine
11
star
26

loda-js

Use JavaScript functionally, you shall.
JavaScript
10
star
27

ofxSDL

Overrides the openFrameworks windowing system to use SDL rather than GLUT.
C++
9
star
28

unflowify

Browserify transform for removing Flow type annotations.
JavaScript
9
star
29

fb-cocoa

Objective-C
8
star
30

remark-comment

Remark plugin to support comments
JavaScript
7
star
31

bubbletype

JavaScript
7
star
32

advent-of-code-2016

Solutions to the Advent of Code 2016 puzzles
JavaScript
6
star
33

dotfiles

JavaScript
6
star
34

ecmascript-reduced

Proposal for short-circuiting Array.prototype.reduce()
JavaScript
4
star
35

leebyron.github.io

Who has business cards anymore?
TypeScript
4
star
36

shapetween

(ARCHIVED 2007) Processing Library for tween and shape curves
Java
4
star
37

Wesley

Snipes
JavaScript
3
star
38

dbmd

Dropbox Hosted Markdown based CMS
JavaScript
3
star
39

iFBG

3
star
40

chain-js

A reactive framework.
JavaScript
2
star
41

cocoa-fbg

2
star
42

of-xcode-templates

openFrameworks XCode Templates
C++
2
star
43

shitty-peg

A Shitty PEG Parser
JavaScript
2
star
44

codespaces-dotfiles

Shell
2
star
45

lisp

Let's Learn Lisp with Lee
JavaScript
1
star
46

phagos

Button Mashing Glutton
C++
1
star
47

nuri-dog

http://nuri.dog
HTML
1
star
48

cocoa-net-connection

Cocoa class which monitors net connectivity
Objective-C
1
star
49

lrumap

JavaScript
1
star