awaiting

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

  • 所有者: hunterloftis/awaiting
  • 平台:
  • 許可證:
  • 分類:
  • 主題:
  • 喜歡:
    0
      比較:

Github星跟蹤圖

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

主要指標

概覽
名稱與所有者hunterloftis/awaiting
主編程語言JavaScript
編程語言JavaScript (語言數: 2)
平台
許可證
所有者活动
創建於2017-04-06 16:15:52
推送於2017-09-01 23:37:18
最后一次提交2017-05-21 19:40:14
發布數15
最新版本名稱v3.0.0 (發布於 2017-05-21 19:39:38)
第一版名稱v1.0.1 (發布於 2017-04-06 12:16:21)
用户参与
星數675
關注者數12
派生數19
提交數148
已啟用問題?
問題數9
打開的問題數3
拉請求數9
打開的拉請求數1
關閉的拉請求數1
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?