npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

awaiting

v3.0.0

Published

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

Downloads

4,474

Readme

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