Wrappy

1.0.2 · maintenance · verified Sun Apr 19

Wrappy is a tiny, foundational utility for reliably wrapping callback functions in JavaScript. Its primary function is to ensure that a given callback is invoked at most once, which is crucial for preventing unexpected behavior in asynchronous operations where a callback might inadvertently be called multiple times. Currently stable at version 1.0.2, released in 2015, the package maintains an extremely low release cadence due to its minimal scope and high stability, with updates typically addressing only critical edge cases or compatibility. Wrappy is largely an internal dependency for many other npm packages (e.g., `once`, `inflight`) rather than a direct application-level utility, providing a robust and dependency-free solution for basic callback management.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `wrappy` to ensure a callback function is executed at most once, even if called multiple times. It includes a basic asynchronous simulation and an example showing how `wrappy` can manage multiple asynchronous completion signals into a single callback trigger.

const wrappy = require('wrappy');

// Define a callback function that we want to ensure runs only once
let executionCount = 0;
function myCallback(err, data) {
  if (err) {
    console.error('Error:', err);
    return;
  }
  executionCount++;
  console.log(`Callback executed! Data: ${data}. Total executions: ${executionCount}`);
}

// Wrap the callback using wrappy
const wrappedCallback = wrappy(myCallback);

// Simulate an asynchronous operation where the callback might be called multiple times
console.log('--- Starting async operation simulation ---');

setTimeout(() => {
  console.log('Attempting to call wrappedCallback (first time)');
  wrappedCallback(null, 'Initial Data');
}, 100);

setTimeout(() => {
  console.log('Attempting to call wrappedCallback (second time - should be ignored)');
  wrappedCallback(null, 'More Data'); // This call should be ignored by wrappy
}, 200);

setTimeout(() => {
  console.log('Attempting to call wrappedCallback (third time - should be ignored)');
  wrappedCallback(null, 'Even More Data'); // This call should also be ignored
}, 300);

// Example of wrappy being used for error handling that only triggers once
function saveUserData(user, callback) {
  const done = wrappy(callback);
  let dbOperationComplete = false;
  let fileWriteComplete = false;

  // Simulate two async operations that need to complete, but only one `done` call
  setTimeout(() => {
    if (Math.random() > 0.9) return done(new Error('DB connection failed'));
    dbOperationComplete = true;
    console.log('DB operation finished.');
    if (fileWriteComplete) done(null, 'User data saved successfully');
  }, 150);

  setTimeout(() => {
    if (Math.random() > 0.9) return done(new Error('File write failed'));
    fileWriteComplete = true;
    console.log('File write finished.');
    if (dbOperationComplete) done(null, 'User data saved successfully');
  }, 250);
}

saveUserData({ id: 1, name: 'Alice' }, (err, result) => {
  if (err) {
    console.error('Save user data failed:', err.message);
    return;
  }
  console.log('Save user data success:', result);
});

view raw JSON →