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

async-barrier

v1.0.0

Published

Helper function to increase your expresiveness when async/await testing

Downloads

1,977

Readme

AsyncBarrier

Helper function to increase your expresiveness when async/await testing

Quick Use

Install with npm:

npm install async-barrier

Just require or import the make function and create a barrier. This barrier will ensure that all async functions reaches the desired line at the same time.

const makeAsyncBarrier = require("async-barrier");

test("setTimeout executes in next tick", async () => {
  const log = [];
  const barrier = makeAsyncBarrier(2);

  setTimeout(async () => {
    log.push("timeout");
    await barrier();
  });

  log.push("begin");
  await barrier();
  log.push("end");

  expect(log).toEqual(["begin", "timeout", "end"]);
});

By omitting the await keyword it can be used to define checkpoints and force async events to happen in the desidered order.

const makeAsyncBarrier = require("async-barrier");

test("setTimeout executes in next tick", async () => {
  const log = [];
  const endTimeout = makeAsyncBarrier(2);

  setTimeout(async () => {
    log.push("timeout");
    endTimeout();
  });

  log.push("begin");
  await endTimeout();
  log.push("end");

  expect(log).toEqual(["begin", "timeout", "end"]);

Motivation

Async/await are hard to test specially when we need a fine grain specification. If you try to use promises to create checkpoints and control async execution order code can become difficult to read. For example, the following code is equivalent to the previous test:

test("setTimeout executes in next tick", async () => {
  const log = [];
  let endTimeoutResolve;
  let endTimeoutPromise = new Promise(resolve => {
    endTimeoutResolve = resolve;
  });

  setTimeout(async () => {
    log.push("timeout");
    endTimeoutResolve();
  });

  log.push("begin");
  await endTimeoutPromise;
  log.push("end");

  expect(log).toEqual(["begin", "timeout", "end"]);
});

makeAsyncBarrier

const barrier = makeAsyncBarrier(2);

It creates a barrier function and returns it. The argument that receives is an integer and represents the number of times that the barrier function will be executed. The created barrier function receives no arguments and returns a promise. The promise returned will be satisfied when the barrier function is executed as many times as indicated in makeAsyncBarrier argument.

Multiple barriers

Each barrier function created with makeAsyncBarrier is independent and represents a different barrier. Each function will only wait for its own calls.

You can use multiple barriers to synchronize steps:

const makeAsyncBarrier = require("async-barrier");

test("synchronize multiple steps in the correct order", async () => {
  const log = [];
  const beginStep1 = makeAsyncBarrier(2);
  const beginStep2 = makeAsyncBarrier(2);
  const endStep2 = makeAsyncBarrier(2);

  (async () => {
    await beginStep2();
    log.push("step 2");
    endStep2();
  })();
  (async () => {
    await beginStep1();
    log.push("step 1");
    beginStep2();
  })();

  log.push("begin");
  beginStep1();
  await endStep2();
  log.push("end");

  expect(log).toEqual(["begin", "step 1", "step 2", "end"]);
});

Excessive calls

Once it is called as many times as indicated in makeAsyncBarrier function argument, next calls have no effect and return a resolved promise.

const makeAsyncBarrier = require("async-barrier");

test("barrier can be called more times that specified", async () => {
  const barrier = makeAsyncBarrier(2);

  barrier();
  barrier();
  await barrier();
});

Don't

Do not wait twice for the same barrier in the same event. It will wait forever:

// don't do this
const barrier = makeAsyncBarrier(2);
await barrier();
await barrier();