Socket
Socket
Sign inDemoInstall

already

Package Overview
Dependencies
0
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.2.0 to 3.3.0

3

dist/index.d.ts

@@ -108,4 +108,5 @@ declare const _default: {

export declare function each<T>(eachFn: EachFn<T>): (t: ConcatArray<T | PromiseLike<T>>) => Promise<Array<T>>;
export declare function each<T>(opts: FilterMapOptions, eachFn: EachFn<T>): (t: ConcatArray<T | PromiseLike<T>>) => Promise<Array<T>>;
export declare function each<T>(arr: ConcatArray<T | PromiseLike<T>>, eachFn: EachFn<T>): Promise<Array<T>>;
export declare function eachImpl<T>(eachFn: EachFn<T>): (t: ConcatArray<T | PromiseLike<T>>) => Promise<Array<T>>;
export declare function each<T>(arr: ConcatArray<T | PromiseLike<T>>, opts: FilterMapOptions, eachFn: EachFn<T>): Promise<Array<T>>;
export declare type SomeReturn<R> = Promise<R | false>;

@@ -112,0 +113,0 @@ export declare type SomeSyncReturn<R> = SomeReturn<R> | R | false;

@@ -229,8 +229,26 @@ export default {

}
export function each(arr, eachFn) {
if (Array.isArray(arr))
return eachImpl(eachFn)(arr);
return eachImpl(arr);
const defaultEachOptions = {
concurrency: 1
};
export function each(arr, opts, eachFn) {
if (Array.isArray(arr)) {
if (typeof opts === "function") {
eachFn = opts;
opts = defaultEachOptions;
}
const _opts = opts;
return eachImpl(_opts, eachFn)(arr);
}
if (typeof arr === "function") {
eachFn = arr;
opts = defaultEachOptions;
}
else {
eachFn = opts;
opts = arr;
}
const _opts = opts;
return eachImpl(_opts, eachFn);
}
export function eachImpl(eachFn) {
function eachImpl(opts, eachFn) {
return async (arr) => {

@@ -242,3 +260,3 @@ const length = arr.length;

}
return map(arr, { concurrency: 1 }, iterator);
return map(arr, opts, iterator);
};

@@ -245,0 +263,0 @@ }

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "3.2.0",
"version": "3.3.0",
"author": "Gustaf Räntilä <g.rantila@gmail.com>",

@@ -8,0 +8,0 @@ "repository": {

@@ -385,3 +385,3 @@ [![npm version][npm-image]][npm-url]

`each` iterates an array of promises or values, very much like `map`, although always serially as if `concurrency` was set to `1`.
`each` iterates an array of promises or values, very much like `map`, although with a default `concurrency` of `1`.

@@ -407,3 +407,26 @@ The iterator function cannot return a value (or it will be ignored), but can return an empty promise which will be awaited before the next iteration. It's like `tap` but for elements in an array.

### Concurrency and time-chunking
Just like `filter` and `map` have [concurrency](#filter-concurrency) and [time-chunking](#filter-operations-chunked-by-idle-time) options, so does `each`. An optional argument before the predicate/iterator function can be used.
For concurrency:
```ts
import { each } from 'already'
await each( array, { concurrency: 4 }, iteratorFun );
```
and for time-chunking:
```ts
import { each } from 'already'
// Time-chunk every 50 milliseconds
await each( array, { chunk: 50 }, iteratorFun );
// Time-chunk dynamically based on requestIdleCallback()
await each( array, { chunk: 'idle' }, iteratorFun );
```
## some

@@ -850,3 +873,3 @@

Many problems can be generalized to only running one function at a time (awaiting it if necessary). For this, the [`throat`](https://www.npmjs.com/package/throat) package is useful (it is used by `already`). Sometimes a more fine grained control is desired, such as allowing a _test and early return_ as well as signalling that the concurrent logic is complete (to allow the next function call) before the whole function is complete. This results in a more understandable flow.
Many problems can be generalized to only running one function at a time (awaiting it if necessary). For this, [`concurrent`](#concurrent) is useful. Sometimes a more fine grained control is desired, such as allowing a _test and early return_ as well as signalling that the concurrent logic is complete (to allow the next function call) before the whole function is complete. This results in a more understandable flow.

@@ -875,3 +898,3 @@ For this, `funnel()` is extremely handy.

The `getConnection` could be wrapped inside a [`throat`](https://www.npmjs.com/package/throat) wrapper, but that wouldn't be as performant as possible. Consider two calls to `getConnection` when there are connections in the pool, but none is free. One of the two calls should create a new connection, but while this takes place (which may take time), another might be freed. This newly freed connection should be re-usable by the second call to `getConnection`.
The `getConnection` could be wrapped inside a [`concurrent`](#concurrent) wrapper, but that wouldn't be as performant as possible. Consider two calls to `getConnection` when there are connections in the pool, but none is free. One of the two calls should create a new connection, but while this takes place (which may take time), another might be freed. This newly freed connection should be re-usable by the second call to `getConnection`.

@@ -878,0 +901,0 @@ `funnel` makes this trivial. Wrap the `getConnection` logic in a funnel. Allow concurrent access to `getReusableConnection` which is concurrency _safe_. Then create a _synchronization barrier_ (using `shouldRetry`/`retry`):

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc