Tuesday, 24 April, 2018 UTC


Summary

When working on a JavaScript project, I usually spend a lot of time around promises. Lately, I’ve been using this helpful function called liftP that makes working with promises a little bit easier.
liftP is a higher-order function that takes a function as a parameter and returns a new function that is “lifted” into a promise. For example, if I have a function that takes a number and returns a string, passing that function through liftP will produce a new function that takes a promise of a number and returns a promise of a string.
Using liftP allows me to design functions without worrying about the structure of a promise around my data types.
Here’s how liftP is implemented:

const liftP = (fn) => {
  return (...args) => {
    return Promise.all(args).then((x) => fn.apply(null, x));
  };
};
Usage

const toString = (x) => `${x}`;
const a = 1;
const b = toString(a); // b === '1'
const toPromiseOfString = liftP(toString); 
const d = Promise.resolve(2);
const e = toPromiseOfString(d); // e is a promise of a string 
const f = await e; // f === '2' 
I’ve found this function most useful when dealing with chains of promises. For example, say I have a function that returns a promise and some other utility functions that process the results of that promise. Instead of writing the utility functions to be aware of the promise structure, I can write the simpler, non-promise implementation.
When I need to chain the utility functions with the function that returns a promise, I can lift the functions when chaining them. In this example, I’m using Ramda’s pipe function to chain a few functions together:

const getUsers = () => {
  return Promise.resolve([
    { firstName: 'Joe', lastName: 'Smith' },
    { firstName: 'Bob', lastname: 'Smith' },
  ]);
};
const getFirstElement = (x) => {
  return x[0];
};
const getFullName = (user) => {
  return `${user.firstName} ${user.lastName}`;
};
const getFullNameOfFirstUser = R.pipe(
  getUsers,
  liftP(getFirstElement),
  liftP(getFullName),
);
const firstUserPromise = getFullNameOfFirstUser(); // Promise of a string
const firstUser = await firstUserPromise; // firstUser === 'Joe Smith'
I hope you find this solution helpful.
The post Lifting Functions into Promises in JavaScript appeared first on Atomic Spin.

Related Stories

  • Incrementally Building My Own Code Health Tool
  • PDF Snapshot Testing with Node and GraphicsMagick
  • Spreading the Spread and Rest Love