icw
is a high-level JavaScript utility library for working with synchronous
and asynchronous iterators in a reactive, stream-like way. By using the
iterator interfaces as a common ground, icw
allows you to use common
stream-like idioms with any data structure that implements Symbol.iterator
or Symbol.asyncIterator
, including built-ins like strings and Arrays, as well
as libraries like @funkia/list
and immutable
.
icw
pairs especially well with Node.js v10's implementation of
ReadableStream
, which has experimental support for the
Symbol.asyncIterator
interface.
The AsyncIterator
interface was added in ECMAScript 2018, so this library
requires a modern JavaScript runtime. We do not currently offer a transpiled
build to support older runtimes.
The library is tested against Node.js >=10, but see the node.green compatibility table for more details on support for asynchronous iterators in Node.js.
For a list of browsers that should support this, see Kangax's ECMAScript 2016+ compatibility table.
npm install --save @icw/icw
or
yarn add @icw/icw
icw
aims to be as idiomatic as possible, in the sense that the API should
closely match any existing native APIs for built-in JavaScript iterables. For
example, all functions are iterable-first, and functions that accept
callbacks – e.g. map
and filter
– should generally have an
optional final argument that allows users to set the this
context for the
callback.
The library does not aim or intend to ever have a currying-friendly API. Currying and data-last APIs are great, but there are some good arguments for why they're not very idiomatic in JavaScript:
- Currying is not idiomatic in JavaScript by Dr Axel Rauschmayer
- Does Curry help? by Hugh FD Jackson
Performance, in terms of operations per second, is not currently a priority for this project. In the words of Johnson & Kernighan (1983), 'the strategy is definitely: first make it work, then make it right, and, finally, make it fast.'
Moreover, because icw
is asynchronous at its core, it will never approach
the peformance of a bare for
loop, Array#forEach
, or any library that
focuses exclusively on synchronous iteration.
In general, if your project involves a lot of async workflows, the high-level
nature of icw
may be worth the trade-off in performance. If your only
iterating over synchronous iterators, however, you would probably be better
off using a library like lodash
or ramda
instead.
That's not to say you can't use icw
for heavily synchronous workloads.
But if you care about Maximum Performance 🚀, the overhead of passing
a bunch of Promises around is probably not what you want.
The Intracoastal Waterway (ICW) is a 3,000-mile (4,800 km) inland waterway along the Atlantic and Gulf of Mexico coasts of the United States […] It provides a navigable route along its length without many of the hazards of travel on the open sea. ― Wikipedia
- Async iterators and generators by Jake Archibald
- ES2018: Asynchronous iteration by Dr Axel Rauschmayer
- Async Iterators: These Promises Are Killing My Performance by Dan Vanderkam
0BSD – See LICENSE
for details.