如何使用带有node.lift-ed函数的when.map?

时间:2015-01-15 14:19:28

标签: javascript node.js functional-programming promise when-js

我通过when.js库学习承诺,并使用when.map与节点fs.readFile让我觉得我错过了一些东西。 foo promise作为单个promise被调用时可以正常工作,但在when.map中用作mapper函数时失败,因为index作为第三个参数被注入(然后回调被传递为第4个)。

API doc说when.map要求mapper函数有两个参数。然后mapper函数可以写成bar,它可以在任何上下文中使用。

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

有没有更优雅的方式来编写bar函数?

1 个答案:

答案 0 :(得分:0)

我认为你误解了partialRight函数的含义。 Lodash文档说明了partialRight

  

此方法与_.partial类似,但部分参数除外   附加到提供给新功能的那些。

你可能认为它与curry相同但是从右边开始,但事实并非如此!它只会将额外的参数附加到参数列表的右侧:

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!"))

产生:

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

在lodash 3.0.0-pre中你应该尝试的函数curryRight,在lodash 2.4.1中没有这样的函数,所以我正在使用哑交换:

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

顺便说一下,感谢简短,自包含,正确的例子!