Skip to content

menduz/fp-future

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A Future is a placeholder object for a value that may not yet exist

Futures are well known data structures, at it's core, futures, are simply promises. This simple package exposes a simple interface on top of promises to leverage a them as boxed value placeholders.

Installation

npm install fp-future

Interface

function future<T>(): IFuture<T>;

type IFuture<T> = Promise<T> & {
  resolve: (x: T) => void;
  reject: (x: Error) => void;
  finally: (fn: () => void) => void;
  isPending: boolean;
}

Usage

Futures are awaitable

const loading = future()

loading.resolve(123)

assert(await loading == 123)

Futures are awaitable and can be rejected

const loading = future()

loading.reject(new Error('It did fail'))

try {
  await loading
} catch(e) {
  assert(e.message == 'It did fail')
}

Promisify is easy too

const loadingFuture = future()

// load(successCallback, errorCallback)
   load(loadingFuture.resolve, loadingFuture.reject)

await loadingFuture

Blackbox testing has never been easier (to read)

It is useful for blackbox testing without weird injections and other magical things.

it("executes the callback", async () => {
  const didClickFuture = future();

  // happy path
  entity.onClick(clickId => {
    didClickFuture.resolve(clickId);
    //             ^^^^^^^^^^^^^^ 
    //             Here we resolve the future with a click
  });

  // unhappy path
  setTimeout(() => {
    didClickFuture.reject(new Error("Timeout"))
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //             Timeout, just in case we don't receive the event
  }, 1000);

  // Generate synthetic event and trigger the event
  const clickId = Math.random()
  entity.triggerClick(clickId);

  // Await the value or fail!
  const receivedNonce = await somethingToBeResolved;

  // Assertion
  expect(receivedNonce).toEq(clickId);
});

Async-awaitable injection of scripts in an HTML

async function injectScript(url: string) {
  const theFuture = future<Event>();
  const theScript = document.createElement("script");
  theScript.src = url;
  theScript.async = true;
  theScript.type = "application/javascript";
  theScript.addEventListener("load", theFuture.resolve);
  theScript.addEventListener("error", e => theFuture.reject(e.error));
  document.body.appendChild(theScript);
  return theFuture;
}

async function main() {
  await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js");
  await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-analytics.js");
  await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js");

  // use the injected scripts
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();
}

Load image data

async function loadImageData(src: string): Promise<ImageData> {
  const futureColors = future<ImageData>();

  var img = new Image();
  img.crossOrigin = "Anonymous"
  img.onload = function() {
    var imageData = loadingContext.getImageData(0, 0, img.width, img.height);

    futureColors.resolve(imageData);
  };

  img.src = src;

  return futureColors;
}

About

A Future is a placeholder object for a value that may not yet exist

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published