npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

easy-cancelable-promise

v2.0.0

Published

CancelablePromise is a Promise that can be canceled. It is a Promise that has a status property that can be '`pending`', '`resolved`', '`rejected`' or '`canceled`'. It has an onCancel method that allows you to register a callback that will be called when

Readme

easy-cancelable-promise

Image John Avatar

Hello and welcome to easy-cancelable-promise, a streamlined and efficient solution for managing asynchronous operations in JavaScript with the elegance of cancelable promises! 🌟

Asynchronous programming is a cornerstone of JavaScript development, and promises are its heartbeat. With easy-cancelable-promise, you elevate your coding experience by introducing the ability to cancel promises - a feature that adds a new layer of control and sophistication to your asynchronous logic.

Whether you're developing with vanilla JavaScript, TypeScript, or integrating with various JavaScript frameworks, easy-cancelable-promise offers you the tools to efficiently manage promise states like 'pending', 'resolved', 'rejected', or the unique 'canceled'. This library is not just about cancellation; it's about enhancing the way you handle asynchronous patterns in your applications.

Experience a new realm of possibility in promise handling with easy-cancelable-promise:

What Does a CancelablePromise Look Like?

Quick Start

Here's a simple example showing how to create and cancel a promise:

import CancelablePromise from 'easy-cancelable-promise';

// Create a cancelable timeout
const promise = new CancelablePromise((resolve, reject, { onCancel }) => {
  const timeoutId = setTimeout(() => resolve('Done!'), 5000);

  onCancel(() => {
    clearTimeout(timeoutId);
    console.log('Timeout cleared!');
  });
});

// Cancel after 1 second
setTimeout(() => promise.cancel('User canceled'), 1000);

promise
  .then((result) => console.log(result))
  .catch((error) => console.log('Canceled:', error));

console.log(promise.status); // 'pending'
// After 1 second: 'canceled'

A cancelable promise looks just like a native promise, and, like the native promise, you can use it with async/await or with callbacks like then and catch.

const result = new CancelablePromise(
  (resolve, reject, { onCancel, reportProgress, cancel }) => {
    // ...your asynchronous code
  },
);

The promise constructor receives an extra parameter with:

cancel: (reason?: unknown) => CancelablePromise

A method that allows you to cancel the promise from its inner scope.

onCancel: (callback: TCancelCallback) => Subscription

A method that allows you to subscribe to the cancel event of the promise. This is especially useful when you need to perform a specific action when the promise is canceled, like aborting an HTTP request or closing a socket.

reportProgress: (percentage: number, metadata?: unknown) => void

A method that allows you to report the progress of the promise. This is especially useful when you have an async operation that could take a long time and you want to report progress to the user.

Let's take a look at the code:

const result = new CancelablePromise(
  async (resolve, reject, { onCancel, reportProgress, cancel }) => {
    const abortController = new CancelableAbortController();

    const request = fetch(
      'https://jsonplaceholder.typicode.com/todos/',
      abortController,
    );

    const unsubscribe = onCancel(() => {
      abortController.abort();
    });

    const results = await request;

    // the async process is not cancellable anymore
    unsubscribe();

    const todosById = await results.json().then((data) => {
      const total = data.length;
      const progressPerItem = 100 / total;

      return data.reduce((accumulator, item) => {
        accumulator[item.id] = item;

        reportProgress(progressPerItem);

        return accumulator;
      }, {});
    });

    // if you need you can cancel the promises it self whenever you want
    // cancel();

    resolve(todosById);
  },
)
  .then((result) => {
    console.log(`%cReady!!!`, 'color: blue; font-weight: bold;', result);
  })
  .onProgress((progress) => {
    console.log(`%ccomplete: ${progress}%`, 'color: blue; font-weight: bold;');
  })
  // .cancel() // you can also cancel the promise whenever you want from outside the promise
  .catch((error) => {
    // in case of error
  });

The same promise handles its own cancellation policy and resource cleanup. This promise can also send feedback, like progress updates, throughout the entire hierarchy. You can have multiple subscriptions to the onCancel callback to implement different resource release strategies as your task progresses.

const result = new CancelablePromise(
  async (resolve, reject, { onCancel, reportProgress, cancel }) => {
    // set resources

    let unsubscribe = onCancel(() => {
      // if something needs to be cleaned up or released at this point
    });

    // do something and wait for it to finish

    unsubscribe();

    // do something else

    // if something needs to be cleaned up or released at this point
    // add a new onCancel listener
    unsubscribe = onCancel(() => {
      // ...
    });
  },
);

You can also add an onCancel listener from outside the promise body. The method for unsubscribing is similar to that used with the fetch AbortController

const abortController = new CancelableAbortController();

const result = new CancelablePromise((resolve, reject) => {
  // ... do something
})
  .onCancel((progress) => {}, abortController)
  .onProgress((progress) => {}, abortController);

// if you want to remove the callback listeners
abortController.abort();

// OR

// also removing specific listeners is super easy
const [_, unsubscribeProgress] = abortController.subscriptions;

unsubscribeProgress();

The AbortController is meant to be used just once, so after calling the abort method, all listeners will be removed (This is the native behavior of the AbortController)

Don't wait any longer!

Unlock the full potential of promises in JavaScript with easy-cancelable-promise and revolutionize the way you approach asynchronous programming!

Don't just take our word for it; explore the capabilities yourself with detailed API documentation below. 🚀

For more information, see the documentation and examples below. You can also check out other libraries that implement cancelable promises, such as easy-web-worker and easy-threads-workers.

CancelablePromise

A Promise that can be canceled. Has a status property ('pending', 'resolved', 'rejected', or 'canceled'), an onCancel method to register cancellation callbacks, and a cancel method.

Examples:

const promise = new CancelablePromise((resolve, reject, utils) => {
  utils.cancel('canceled');
});

promise.catch((reason) => {
  console.log(reason); // 'canceled'
  console.log(promise.status); // 'canceled'
});

Properties

  • status: TPromiseStatus - Current promise status ('pending' | 'resolved' | 'rejected' | 'canceled')

Methods

  • onCancel: Subscribe to the cancel event
  • onProgress: Subscribe to progress reports
  • cancel: Cancel the promise

defer

Creates a deferred promise with separate resolve/reject functions.

Example

import { defer } from 'easy-cancelable-promise';

const { promise, resolve } = defer<string>();
promise.then((result) => console.log(result));

resolve('hello world');
// hello world

toCancelablePromise

Converts a Promise, CancelablePromise, or value to a CancelablePromise.

import { toCancelablePromise } from 'easy-cancelable-promise';

const promise = Promise.resolve('hello');
const cancelable = toCancelablePromise(promise);
cancelable.cancel();

groupAsCancelablePromise

Groups multiple promises into a single CancelablePromise with concurrency control.

Config options:

  • maxConcurrent: Max concurrent execution (default: 8)
  • executeInOrder: Execute sequentially (default: false)
  • beforeEachCallback: Called before each execution
  • afterEachCallback: Called after each success
  • onQueueEmptyCallback: Called when all complete
import { groupAsCancelablePromise } from 'easy-cancelable-promise';

const group = groupAsCancelablePromise([promise1, promise2], {
  maxConcurrent: 2,
});
group.cancel(); // Cancels all pending

Type Guards

  • isPromise(value): Checks if a value is a Promise
  • isCancelablePromise(value): Checks if a value is a CancelablePromise
  • isCancelableAbortSignal(signal): Checks if an AbortSignal is a CancelableAbortSignal

Contributing

We welcome contributions to easy-cancelable-promise! If you have an idea for a new feature or improvement, please open an issue or submit a pull request.

License

easy-cancelable-promise is released under the MIT License.