• Stars
    star
    674
  • Rank 66,980 (Top 2 %)
  • Language
    JavaScript
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

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

Repository Details

The async/await utility for browsers and Node.js.

Awaiting

The async/await utility for browsers and Node.js.

API Docs | Installation | Examples | Motivation | API Overview

  • Node.js >= 7.6.0
  • Edge >= 15
  • Firefox >= 52
  • Chrome >= 55
  • Safari >= 10.1
  • Opera >= 44
  • iOS Safari >= 10.3

Build Status Coverage Status

Installation

In node

Use yarn or npm:

$ yarn add awaiting
$ npm install --save awaiting

then:

const a = require('awaiting')

main()

async function main() {
  await a.delay(1000)
}

In a browser

Use dist/awaiting.umd.js:

<script src='awaiting.js'></script>
<script>
  const a = awaiting

  main()

  async function main() {
    await a.delay(1000)
  }
</script>

With Babel

import whatever you want, you hipster.

Examples

Check out a live example in your browser, then view the source.

// wait for a second
await a.delay(1000)

// limit a fetch to five seconds
const image = await a.limit(fetch('flowers.jpg'), 5000)

// await events
await a.event(server, 'listen')

// await callbacks
const contents = await a.callback(fs.readFile, 'foo.txt')

// map an array to an async function with 3 instances running in parallel
const pages = await a.map(urls, 3, fetch)

// await successes (ignoring errors)
const file = await a.success(getNetworkFile())

...and more in the API Docs.

Motivation

I love the async/await pattern. Code written with async functions benefits from superior readability, improved terseness and expressiveness, and unified error handling. No more nested callbacks, opaque Promise chains, and if (err) checks littering your code.

However, this pattern isn't a panacea. It's easy to do some things: iterate through single items, wait on a single result, run an array of promises in parallel. Other workflows require abstraction or state. I kept finding myself writing the same utility functions in each project: delays, throttled maps, skipping try/catch on optional operations, adapting to events or callbacks. Await, combined with these simple abstractions, yields readable yet powerful async workflows.

Why now? Node v7.6.0 enabled non-transpiled, non-flagged, out-of-the-box support for async functions. Every major browser has shipped support. If you write for old clients, you can still use this via Babel. Async functions are already here.

Why not something like Bluebird? This is heavily inspired by libraries like Bluebird and Async, which both aim to make non-trivial async workflows more readable.

However, these problems shouldn't be solved by replacing native Promise implementations with custom versions, as Bluebird and Q attempt. Having multiple, conflicting definitions of Promise in a codebase means you now have to check the capabilities of a given Promise before using it. This decreases interoperability and increases fragmentation - and dependency bloat. It's not uncommon for a single app to depend on two or three subtly different Promise implementations.

We've been here before, back when extending Object prototypes was the norm. We've seen how painful it is to have different libraries extending or replacing built-ins like Promise with conflicting implementations of custom behavior.

Node's 'unhandledRejection' event illustrates why interoperability is so important: if you're using non-standard Promises, you can't catch that event. If your app and dependencies use a mix of 3rd party and native Promises, some of the Promise rejections in your app will be caught while others are not. If you've ever used a library that returned some sort of "Promise," but you had to dive into the source to find out exactly which implementation and custom behavior it exposed, you've also experienced the pain of fragmentation.

Instead, awaiting follows the example of lodash and underscore, which chose not to replace or extend native Arrays and Objects, but instead provided functional utilities for them.

API Overview

This illustrates use cases for each utility. For details, see the full API docs.

Use this when you want to...

  • callback: treat a callback function (like one of the core node APIs) as an async function.
  • delay: wait for some time to pass.
  • event: treat an EventEmitter's event (like server.on('listen')) as an async function.
  • failure: inspect the Error from a probable failure (vs throwing / exiting)
  • limit: limit the runtime of an async function so your program doesn't hang.
  • list: wait for a list of async functions to resolve simultaneously, possibly ignoring some number of rejections.
  • map: wait for a list of async functions to resolve, limiting how many run simultaneously to avoid running out of memory or hammering a server with too many requests.
  • object: resolve several async functions simultaneously which are stored as properties of an object.
  • result: wait for an async function to resolve or reject, then check to see whether it returned a result or an Error.
  • set: wait for a minimum set of async functions to resolve, such as pinging a dozen servers and seeing which two are fastest.
  • single: wait for a single async function to resolve from a list.
  • success: ignore the result of an async function (undefined) if it fails.
  • swallow: use someone else's module that throws a lot of unhandled rejection errors.
  • throw: get useful stack traces from your unhandled rejections instead of just console logs.
  • time: wait for a specific time (as a Date object).

Building

$ yarn build

Testing

$ yarn install
$ yarn test
$ yarn test:browser

More Repositories

1

pbr

a Physically Based Renderer (PBR) in Go
Go
1,136
star
2

newton

A playful, particle-based physics engine designed from the ground up for JavaScript.
JavaScript
917
star
3

throng

A simple worker-manager for clustered Node.js apps
JavaScript
856
star
4

playfuljs-demos

680
star
5

playfuljs

www.playfuljs.com
CSS
520
star
6

stoppable

Node's `server.close` the way you expected it to work.
JavaScript
403
star
7

jackrabbit

Simple AMQP / RabbitMQ job queues for node based on amqplib
JavaScript
293
star
8

cryo

JSON on steroids.
JavaScript
157
star
9

oneweekend

Ray Tracing book series implemented in Golang, chapter-by-chapter
Go
153
star
10

notes

Notes about things.
147
star
11

knockout.namespaces

Namespaces plugin for KnockoutJS
JavaScript
57
star
12

pathtracer

A simple, naive path tracer in JavaScript
JavaScript
50
star
13

summarize

Node.js module to extract and summarize html content
JavaScript
41
star
14

pbr2

Go
38
star
15

component-test

An experiment to see what a simple node app would look like with "Components" from the @visionmedia blog
JavaScript
29
star
16

nodevember-14

JavaScript
28
star
17

heroku-node-errcodes

Examples of intentionally triggering various Heroku H* errors with Node.js
JavaScript
21
star
18

heroku-destroy-temp

Heroku CLI plugin to destroy temporary apps.
JavaScript
13
star
19

ludumstar

JavaScript
12
star
20

backbone.viewmodel

ViewModels with UI Bindings for Backbone (ala KnockoutJS, Flex, .NET, MVVM pattern)
JavaScript
7
star
21

dotfiles

personal dotfiles (steam deck dev machine)
Shell
7
star
22

itemize

A lazy, fluent web crawler for Node.js with a modern async/await API.
JavaScript
6
star
23

heroku-cli-node

A Heroku CLI plugin for Node.js app development
JavaScript
5
star
24

tetrinet

JavaScript
5
star
25

node-boilerplate

Structure for your node.js project
JavaScript
4
star
26

lanes

Simple, generic, sticky routing for clustered Node.js apps
JavaScript
4
star
27

server-jsx

Render react views on your node.js server
JavaScript
4
star
28

blit

2D Sprites that render to WebGL
JavaScript
4
star
29

cltjs-node

Node.js in 30 minutes
JavaScript
3
star
30

nko-quickstart

"Hello, world" with deployment instructions.
JavaScript
3
star
31

mongoose-file

Attach a file to a mongoose Schema
JavaScript
3
star
32

docker-plugin

JavaScript
3
star
33

babylonterrain

Testing babylonjs with terrain generation
JavaScript
3
star
34

music-city-game

Workshop for Music City Code 2019
JavaScript
3
star
35

storj

An attempt at the interesting Storj challenge
Go
2
star
36

blitzkrieg

Middleware to provide an authorized domain for blitz.io load testing in Node.js.
JavaScript
2
star
37

space-snake

Ludum Dare 38: A Small World
JavaScript
2
star
38

node-production

Running Node all the way from development to production on Heroku.
JavaScript
2
star
39

okay.js

A knockout knockoff
JavaScript
2
star
40

get-large-json

Test for getting large in-memory json objects
JavaScript
2
star
41

hunterloftis.com

Personal homepage
JavaScript
2
star
42

heroku-buildpack-sfdx

Shell
1
star
43

heroku-buildpack-empty

Quick example of a no-op buildpack
Shell
1
star
44

simplenode

A simple boilerplate for single-page node projects deployable on Ubuntu VPS.
JavaScript
1
star
45

heroku-node-template

Easily template new node projects with best practices for Heroku.
JavaScript
1
star
46

ld39

JavaScript
1
star
47

backpacksncats

Our blog
CSS
1
star
48

Quarry

JavaScript
1
star
49

node-dev-env

Dockerfile
1
star
50

arduino_wiimotionplus

Reading wii motionplus data with the arduino
C++
1
star
51

handoff

JavaScript
1
star
52

socket.io-chat-distributed

Socket.io chat scaled across multiple nodes, backed by redis
HTML
1
star
53

df-micro-web

JavaScript
1
star
54

deno-pointers

Testing out Deno with a little state
TypeScript
1
star
55

game-workshop

JavaScript
1
star
56

dogfight

JavaScript
1
star
57

mongoose-timestamps

A simple mongoose plugin for storing last created and last modified information
1
star
58

loopbusy

Node.js middleware to send 503s and keep your server alive when it's too busy to queue more requests.
JavaScript
1
star
59

processing_wiimotionplus

Renders position data sent over serial by the WMP Arduino code
Java
1
star