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 🙏

© 2024 – Pkg Stats / Ryan Hefner

compromiser

v1.0.4

Published

A Promise that's also a callback. Helpful for adapting callback APIs and event emitters for async/await code.

Downloads

19

Readme

compromiser

A Promise that's also a callback. Helpful for adapting callback APIs and event emitters for async/await code.

build status

Installation

This module is installed via npm:

$ npm install compromiser

Background

Promises are great, and tools like util.promisify() help to convert callbacks to promises, but fall short of many other use case such as event emitters, which makes writing neat async/await code really annoying if you want to wait for the result before continuing execution.

Here's a typical example WITHOUT using compromiser where you have to wrap the async stuff inside a promise and await on it, otherwise the control flow would 'fall through':

async function main() {
  let contents = '';
  // have to wrap async work inside a promise so you can await for it.
  let p = new Promise((resolve, reject) => {
    fs.createReadStream('/etc/passwd', 'utf8')
      .on('data', (chunk) => contents += chunk)
      .once('error', reject)
      .once('end', () => resolve(contents));
  });
  try {
    // if we don't await for the promise above, we would fall through here when we
    // want to "block" and wait for the async behaviour to complete.
    let data = await c;
    console.log(data);
    // prints out contents of /etc/passwd
  } catch (err) {
    console.error(err);
  }
}
main().catch(console.error);

Here's the same code using compromiser:

const compromiser = require('compromiser');
const fs = require('fs');

async function main() {
  let contents = '';
  let c = compromiser();
  // pass `c.reject` or `c.resolve` through to regular event emitter functions
  fs.createReadStream('/etc/passwd', 'utf8')
    .on('data', (chunk) => contents += chunk)
    .once('error', c.reject)
    .once('end', () => c.resolve(contents));

  try {
    let data = await c;
    console.log(data);
    // prints out contents of /etc/passwd
  } catch (err) {
    console.error(err);
  }
}
main().catch(console.error);

Standard Callback Example

And if you can't be bothered promisifying everything then you can use compromiser to resolver promises by passing in c.callback where a regular error-first callback would be expected:

const compromiser = require('compromiser');
const fs = require('fs');

async function main() {
  let c = compromiser();
  fs.readFile('/etc/passwd', 'utf8', c.callback);
  try {
    let data = await c;
    console.log(data);
    // prints out contents of /etc/passwd
  } catch (err) {
    console.error(err);
  }
}
main().catch(console.error);

Multiple callback arguments

There are a few callbacks that may take multiple callback arguments. To get these, you can pass through true as the argument for compromiser() which will spread the callback arguments and return them as an array.

Here's an example with request:

const request = require('request');
const compromiser = require('compromiser');

async function main() {
  let c = compromiser(true);
  request('http://example.com/test.html', c);
  try {
    // the two return variables in the (err, response, body) callback will
    // be returned in an array.
    let [response, body] = await c;
    console.log(response, body);
  } catch (err) {
    // the error will appear here
    console.error(err);
  }
}
main().catch(console.error);

API

compromiser([spread = false])

Creates a new instance of a compromiser Promise. Passing true through as the spread argument will return multiple callback arguments back as an array.

The default is false.

The instance of compromiser is a Promise. It does have a few other methods added which are detailed below.

compromiser#resolve(value)

Resolve the underlying promise

compromiser#reject(err)

Reject the underlying Promise with an error.

compromiser#callback(err, results)

Returns a node.js thunk (a function with the signature c(err, results).

Pass this to a node.js style callback and then based on the result of the callback, the undelrying Promise will be resolved/rejected.

If the compromiser was created with spread = true then you can call this function with multiple callback results and they will be resolved as an array.