or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Async Each

Async Each is an ultra-simple, lightweight JavaScript library that provides asynchronous parallel iteration over arrays. It offers a no-bullshit, 35-lines-of-code solution for processing arrays concurrently with error handling and result transformation, without the overhead of larger async libraries.

Package Information

  • Package Name: async-each
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install async-each

Core Imports

const each = require('async-each');

For AMD (RequireJS):

define(['async-each'], function(each) {
  // use each
});

For browser (global):

// Available as window.asyncEach
asyncEach(array, iterator, callback);

Basic Usage

const each = require('async-each');
const fs = require('fs');

// Process files in parallel
each(['file1.txt', 'file2.txt', 'file3.txt'], fs.readFile, function(error, contents) {
  if (error) {
    console.error('Error reading files:', error);
    return;
  }
  console.log('File contents:', contents);
});

// Transform data in parallel
each([1, 2, 3, 4, 5], function(item, done) {
  // Simulate async operation
  setTimeout(() => {
    done(null, item * 2);
  }, 100);
}, function(error, results) {
  if (error) {
    console.error('Error:', error);
    return;
  }
  console.log('Results:', results); // [2, 4, 6, 8, 10]
});

Capabilities

Parallel Array Processing

Processes array items asynchronously in parallel, maintaining original array order in results.

/**
 * Asynchronous parallel forEach function for arrays
 * @param items - Array of items to process
 * @param next - Iterator function called for each item
 * @param callback - Optional completion callback
 */
function each(items, next, callback);

Parameters:

  • items (Array, required): Array of items to process. Must be an array, throws TypeError if not.
  • next (Function, required): Iterator function called for each item. Signature: next(item, done)
    • item: Current array item being processed
    • done: Callback function with signature done(error, transformedItem)
      • error: Error value (any truthy value treated as error)
      • transformedItem: Optional transformed result for this item
  • callback (Function, optional): Completion callback. Signature: callback(error, results)
    • error: Error object if any iteration failed, undefined on success
    • results: Array of transformed items in original order
    • Defaults to no-op function if not provided

Behavior:

  • Processes all array items concurrently (parallel execution)
  • Maintains original array order in results
  • Stops execution on first error and calls callback with error
  • Returns undefined (no return value)
  • Creates results array with same length as input array

Error Handling:

  • Throws TypeError if items is not an array
  • Throws TypeError if next is not a function
  • Calls callback with Error object if any iterator returns an error
  • Iterator errors are wrapped in new Error() constructor

Usage Examples:

const each = require('async-each');

// File processing example
each(['config.json', 'data.json'], require('fs').readFile, function(error, files) {
  if (error) return console.error(error);
  console.log('Loaded files:', files.map(f => f.toString()));
});

// Data transformation example
each(['hello', 'world'], function(item, done) {
  done(null, item.toUpperCase());
}, function(error, results) {
  console.log(results); // ['HELLO', 'WORLD']
});

// Error handling example
each([1, 2, 3], function(item, done) {
  if (item === 2) {
    done('Error processing item 2');
  } else {
    done(null, item * 10);
  }
}, function(error, results) {
  if (error) {
    console.error('Processing failed:', error); // "Error processing item 2"
  }
});

// Without callback (fire and forget)
each([1, 2, 3], function(item, done) {
  console.log('Processing:', item);
  done(null, item);
});

Types

For TypeScript users, the effective type definitions are:

type IteratorFunction<T, R> = (
  item: T, 
  done: (error?: any, result?: R) => void
) => void;

type CompletionCallback<R> = (
  error?: Error, 
  results?: R[]
) => void;

function each<T, R>(
  items: T[], 
  next: IteratorFunction<T, R>, 
  callback?: CompletionCallback<R>
): void;

Environment Compatibility

  • Node.js: Full support via CommonJS export (module.exports)
  • Browser: Global export as window.asyncEach
  • AMD/RequireJS: AMD module support
  • ES Modules: Supported via CommonJS interop (e.g., import each from 'async-each')

Error Patterns

Common error scenarios and handling:

const each = require('async-each');

// Invalid arguments
try {
  each('not-an-array', function() {}, function() {});
} catch (error) {
  console.error(error.message); // "each() expects array as first argument"
}

try {
  each([], 'not-a-function', function() {});
} catch (error) {
  console.error(error.message); // "each() expects function as second argument"
}

// Iterator error handling
each([1, 2, 3], function(item, done) {
  if (item === 2) {
    done('Custom error message');
  } else {
    done(null, item);
  }
}, function(error, results) {
  if (error) {
    console.error('Error occurred:', error.message); // "Custom error message"
  }
});