简体   繁体   中英

How to use when.map with node.lift-ed function?

I'm learning promises with when.js library, and using when.map with node fs.readFile makes me think I missed something. foo promise works ok when called as a single promise, but fails when used as a mapper function in when.map because index is injected as a third parameter (and then callback is passed as 4th).

API doc says that when.map has a requirement for mapper function to have two parameters. Then mapper function can be written as bar , and it works in any context.

var when = require('when');
var node = require('when/node');
var _ = require('lodash');

// readFile has the same signature as fs.loadFile
function readFile(param1, param2, callback) {
  console.log(Array.prototype.slice.call(arguments));
  callback(null, [param1, param2]);
}

var foo = _.partialRight(node.lift(readFile), 'base64');

var bar = function (fileName, index) {
  return node.lift(readFile)(fileName, 'base64');
};

when.map(['1', '2'], bar).done(); // works
when.map(['3', '4'], foo).done(); // does not work

Is there any more elegant way to write bar function?

I think you misinterpret the meaning of partialRight function. Lodash documentation states for partialRight that

This method is like _.partial except that partial arguments are appended to those provided to the new function.

You, probably, thought that it is same as curry but goes from the right, but it's not! It will just append the extra arguments to the right of argument list:

function baz() {
    console.log(arguments)
}

var qux = _.partialRight(baz, 'should be second parameter, but is not')

console.log(qux("first parameter", "second parameter, should be ignored, but it's not!"))

which produces:

 { '0': 'first parameter', '1': 'second parameter, should be ignored, but it\\'s not!', '2': 'should be second parameter, but is not' } 

In lodash 3.0.0-pre there's function curryRight which you should try, in lodash 2.4.1 there're no such function, so I'm using dumb swap:

var when = require('when');
var node = require('when/node');
var _ = require('lodash');

function readFile(param1, param2, callback) {
  console.log(Array.prototype.slice.call(arguments));
  callback(null, [param1, param2]);
}


/* Swaps arguments of function with two arguments*/
function swap(f) {
    return function (a,b) {
        return f(b,a);
    }
}



var foo = _.curry(swap(node.lift(readFile)))("base64")



var bar = function (fileName, index) {
  return node.lift(readFile)(fileName, 'base64');
};



when.map(['1', '2'], bar).done(); // works
when.map(['3', '4'], foo).done(); // does work

BTW, thanks for Short, Self Contained, Correct Example!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM