Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to promisify a function when the callback takes multiple arguments

Is there any way to promisify a function where the callback takes more than two arguments? An example is node's fs.read, where the three arguments of the callback are err, bytes and data. The data argument doesn't get passed to the then function, so this logs undefined:

var fs = require('fs');
var Promise = require('bluebird');
var open = Promise.promisify(fs.open);
var read = Promise.promisify(fs.read);

open('test.txt', 'r')
  .then(function(fd) {
    var buffer = new Buffer(1024);
    read(fd, buffer, 0, buffer.length, null).then(function(bytes, data) {
      console.log(data);
    });
  });
like image 214
kanthoney Avatar asked Dec 17 '15 11:12

kanthoney


People also ask

How do you Promisify a callback function?

To convert a callback into a promise, you need to return a promise. You run the code with the callback inside the promise. const readFilePromise = () => { return new Promise((resolve, reject) => { fs. readFile(filePath, options, (err, data) => { // ... }) }) }

How do you Promisify a function in Javascript?

function promisify(f) { return function (... args) { // return a wrapper-function (*) return new Promise((resolve, reject) => { function callback(err, result) { // our custom callback for f (**) if (err) { reject(err); } else { resolve(result); } } args.

Which is faster callbacks or promises?

It's a long debated hot topic between javascript developers what is efficient or fast. Till now common perception was that for getting out of callback hell we should use promises or for clean code but what about efficiency. So from my findings i assure you ES6 promises are faster and recommended than old callbacks.

How do you convert an existing callback API to promises?

If the callback function returns non-error output, we resolve the Promise with the output. Let's start by converting a callback to a promise for a function that accepts a fixed number of parameters: const fs = require('fs'); const readFile = (fileName, encoding) => { return new Promise((resolve, reject) => { fs.


1 Answers

I've answered my question - use the multiArgs option in promisify, and then use spread instead of then:

var fs = require('fs');
var Promise = require('bluebird');
var open = Promise.promisify(fs.open);
var read = Promise.promisify(fs.read, {multiArgs:true});

open('test.txt', 'r')
  .then(function(fd) {
    var buffer = new Buffer(1024);
    read(fd, buffer, 0, buffer.length, null).spread(function(bytes, data) {
      console.log(data);
    });
  });
like image 103
kanthoney Avatar answered Nov 11 '22 05:11

kanthoney