Skip to content

Instantly share code, notes, and snippets.

@nfrasser
Last active March 22, 2017 13:22
Show Gist options
  • Save nfrasser/8a50b66224854938dfbf to your computer and use it in GitHub Desktop.
Save nfrasser/8a50b66224854938dfbf to your computer and use it in GitHub Desktop.
Promise helper method which can be used to convert any Node.js/io.js async function into a Promise. Written in ES6.
import {isArray} from 'lodash';
import {Promise} from 'rsvp';
/**
Make an RSVP promise out of a generic node function that takes a callback as
its last argument.
First argument is either (a) the function to call or (b) an array where the
first element is the context, and the second is the function to call.
Do not pass in the standard callback argument at the end
*/
export default function promise(fn, ...args) {
var context = this;
if (isArray(fn)) { // can replace with `fn instanceof Array`
// context is first param, function is second
[context, fn] = fn;
}
if (typeof fn !== 'function') {
throw new Error("First argument for promise.make must be a function");
}
// Return the promise
return new Promise((resolve, reject) => {
args.push((err, result) => {
if (err) { return reject(err); }
return resolve(result);
});
fn.apply(context, args);
});
}
@nfrasser
Copy link
Author

Usage: The first argument is always the function, and the rest are the parameters that function takes (minus the callback at the end).

import fs from 'fs';
import promise from './promise';

// https://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback
promise(fs.readFile, 'test.txt', {encoding: 'utf8'})
  .then(contents => console.log(contents))
  .catch(err => console.error(err));

If you need the function to use or retain a certain context, pass it in as an array of two elements.

e.g., promise([fs, fs.readFile], ...).

@nfrasser
Copy link
Author

Shorter (but more basic) version:

// promise.js
export default (fn, ...args) => new Promise((resolve, reject) =>
    fn(...args, (err, result) => err ? reject(err) : resolve(result))
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment