Functional directives for Promise and AsyncIterable
npm install async-later  
Return a Promise or an AsyncIterable now and handle the logic later! Use in conjunction with the amazing streaming-iterables package and write elegant functional code.
``bash`
npm i --save async-later
We ship esm and types.
- resolveLater()
- iterateLater()
- partition()
- toAsyncIterable()
- firstValue()
- lastValue()
- valueAt()
- concurrently()
`ts`
function resolveLater
// type Resolve
Creates a Promise and passes its resolve to the outer scope (in the native Promise API, resolve is only accessible through new Promise((resolve, reject) => {...})).
`js
import { resolveLater } from 'async-later';
const [value, setValue] = resolveLater();
value.then(console.log);
setValue(42);
// 42
`
Real world example adapted from @functionland/protocols/file:
`ts
// Customizable backend for "save"
type SaveMethod = (blog: Blog, declareId: (id: string) => void) => any;
// We want to pass a callback, "declareId", to custom implementations
// to be invoked with "id" when they are done
let saveMethod: SaveMethod = async () => {}; // Default: no implementation
export function changeSaveMethod(method: SaveMethod) {
saveMethod = method;
}
export function save(blog: Blog): Promise
const [id, resolve] = resolveLater
saveMethod(blog, resolve);
return id;
}
`
`ts`
function iterateLater
Creates next() and complete() interfaces for an AsyncIterable (similar to Observables). Stalls on back pressure and caches when read is slower.
`js
import { iterateLater } from 'async-later';
const [iterable, next, complete] = iterateLater();
next(1);
next(2);
next(3);
complete();
for await (const value of iterable) {
console.log(value);
}
// 1
// 2
// 3
`
`ts`
function partition
Decomposes an AsyncIterable into two at an index (more partitions can be made by subsequent/recursive calls).
`js
import { partition, toAsyncIterable } from 'async-later';
const [p1, rest] = partition(2, toAsyncIterable([1, 2, 3, 4, 5]));
const [p2, p3] = partition(2, rest);
for await (const value of p1) {
console.log(value);
}
// 1
// 2
for await (const value of p2) {
console.log(value);
}
// 3
// 4
for await (const value of p3) {
console.log(value);
}
// 5
`
`ts`
function toAsyncIterable
value: T | PromiseLike
): AsyncIterable
// Curried overload suitable for pipeline:
export function toAsyncIterable
value: T | PromiseLike
) => AsyncIterable
Converts anything to an AsyncIterable!
`js
import { toAsyncIterable } from 'async-later';
for await (const value of toAsyncIterable(42)) {
console.log(value);
}
// 42
for await (const value of toAsyncIterable(Promise.resolve(42))) {
console.log(value);
}
// 42
for await (const value of toAsyncIterable([42])) {
console.log(value);
}
// 42
for await (const value of toAsyncIterable([])) {
console.log(value); // Will not execute
}
for await (const value of toAsyncIterable([1, 2, 3])) {
console.log(value);
}
// 1
// 2
// 3
for await (const value of toAsyncIterable([1, Promise.resolve(2), Promise.resolve(3)])) {
console.log(value);
}
// 1
// 2
// 3
`
`ts`
function firstValue
// Curried overload suitable for pipeline:
function firstValue
Returns the first value from an AsyncIterable as a Promise. The Promise rejects if iterable is empty.
`js
import { firstValue, toAsyncIterable } from 'async-later';
const iterable = toAsyncIterable([1, 2, 3]);
console.log(await firstValue(iterable));
// 1
`
`ts`
function lastValue
// Curried overload suitable for pipeline:
function lastValue
Returns the last value from an AsyncIterable as a Promise. The Promise rejects if iterable is empty.
`js
import { lastValue, toAsyncIterable } from 'async-later';
const iterable = toAsyncIterable([1, 2, 3]);
console.log(await lastValue(iterable));
// 3
`
`ts`
function valueAt
// Curried overload suitable for pipeline:
function valueAt
Returns the value specified by an index in an AsyncIterable, as a Promise. The Promise rejects if iterable is empty or index >= length.
`js
import { valueAt, toAsyncIterable } from 'async-later';
const iterable = toAsyncIterable([1, 2, 3]);
console.log(await valueAt(1, iterable));
// 2
`
`ts`
function concurrently
Invokes functions with Promise.all.
`js
import { concurrently } from 'async-later';
const result = await concurrently(
() => 42,
() => Promise.resolve(42),
async () => 42,
() => 24,
async () => 24
);
console.log(result)
// [42, 42, 42, 24, 24]
``