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

@liveramp/higher-order-promise

v1.0.5

Published

[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=LiveRamp_higher-order-promise&metric=coverage&token=0b9c07102104a80f0af5478dd78938d7fe245d2d)](https://sonarcloud.io/dashboard?id=LiveRamp_higher-order-promise)

Downloads

12

Readme

Higher Order Promises

Coverage

This package allows you to fluently parallelize asynchronous calls, while retaining type information, and deferring any actual awaiting until your choosing via calling yield().

In english, this means you will spend less time wrangling Promises, and your code will perform better than if you were to naively use awaits.

For examples of usage, check out its tests.

Installation

If you'd like to fiddle around with it, try it out on RunKit!

This package is distributed using NPM. To use in your project:

npm install @liveramp/typed-mutations

In-depth justification

The usual way of handling asynchronous computation in Typescript is leveraging async/await. This is reasonably intuitive while keeping you out of callback hell.

Consider the following snippet:

async function awaitTestSequence() {
  let result1 = await slowPromise("1", 1000, 10);
  let result2 = await slowPromise("2", 1000, 20);

  return result1 + result2
}

function slowPromise<T>(identifier: string, timeout: number, result: T): Promise<T> {
  return new Promise((resolve) => {
    console.log(`Starting promise: ${identifier}`)
    setTimeout(() => {console.log(`Ending promise: ${identifier}`) resolve(result)}, timeout)
  })
}

Calling awaitTestSequence yields output like:

Starting promise: 1
Ending promise: 1
Starting promise: 2
Ending promise: 2

Yet, promise 2 doesn't need anything from promise 1, why wait at all to execute it?

Sure, you can avoid unnecessary waiting in native TS, but the best you can come up with is something like:

async function betterAwaitTestSequence() {
  let [result1, result2] = await Promise.all([
    slowPromise("1", 1000, 10),
    slowPromise("2", 1000, 10)
  ])

  return result1 + result2
}

This is already a little cumbersome even in the simplest case. You lose the ease of having a simple reference to the promise, unless you manually wrangle indices or use a destructuring approach. If you add a promise, you'll need to update to destructure that instance. Readability is hurt, as you have to mentally associate which promise is which index. In short, order matters here, but it shouldn't.

Further, Promise.all has a limitation on supporting only 10 promises before type information is lost.

Finally, let's imagine you wanted to use result1 or result2 to trigger further asynchronous work. This requires even more wrangling.

Instead, HigherOrderPromise provides a different abstraction. It lets you build objects which contain asynchronous properties, then compose operations on top of them.

Here's an example of the above using Await

HigherOrderPromise.from({
  result1: slowPromise("1", 1000, 10),
  result2: slowPromise("2", 1000, 10)
}).then((data) => {
  return data.result1 + data.result2
}).yield()