Adapter
ary
创建一个函数,该函数接受最多 n
个参数,忽略任何其他参数。
调用提供的函数 fn
,参数最多为 n
个,使用 Array.prototype.slice(0,n)
和 spread 操作符(...
)提取并传入参数。
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
const firstTwoMax = ary(Math.max, 2); [[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
call
给定一个 key
和一组参数,在给定上下文时调用它们。主要用于函数组合。
使用闭包以存储的参数调用存储的 key
。
const call = (key, ...args) => context => context[key](...args);
Promise.resolve([1, 2, 3]) .then(call('map', x => 2 * x)) .then(console.log); // [ 2, 4, 6 ] const map = call.bind(null, 'map'); Promise.resolve([1, 2, 3]) .then(map(x => 2 * x)) .then(console.log); // [ 2, 4, 6 ]
collectInto
Changes a function that accepts an array into a variadic function.
Given a function, return a closure that collects all inputs into an array-accepting function.
将接受数组的函数改变为接收可变参数函数。
给定一个函数,返回一个闭包,该闭包将所有输入收集到一个接受数组的函数中。
const collectInto = fn => (...args) => fn(args);
const Pall = collectInto(Promise.all.bind(Promise)); let p1 = Promise.resolve(1); let p2 = Promise.resolve(2); let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3)); Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)
flip
接受一个函数作为参数,然后将该函数第一个参数作为最后一个参数。(注:翻转参数)
返回一个接受可变参数输入的闭包,并且在应用其余参数之前将最后一个参数作为第一个参数。
const flip = fn => (first, ...rest) => fn(...rest, first);
let a = { name: 'John Smith' }; let b = {}; const mergeFrom = flip(Object.assign); let mergePerson = mergeFrom.bind(null, a); mergePerson(b); // == b b = {}; Object.assign(b, a); // == b
over
创建一个函数,该函数使用接收到的参数调用所提供的每个函数并返回结果。
使用 Array.prototype.map()
和 Function.prototype.apply()
将每个函数应用于给定的参数。
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
const minMax = over(Math.min, Math.max); minMax(1, 2, 3, 4, 5); // [1,5]
overArgs
创建一个函数,该函数调用所提供的函数并对传入的参数进行转换。
使用 Array.prototype.map()
将 transform
应用于 args
,并结合扩展操作符 (...
) 将转换后的参数传递给 fn
。
const overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));
const square = n => n * n; const double = n => n * 2; const fn = overArgs((x, y) => [x, y], [square, double]); fn(9, 3); // [81, 6]
pipeAsyncFunctions
为返回的异步函数,从左到右依次执行函数组合。
使用 Array.prototype.reduce()
和扩展操作符 (...
) ,并结合Promise.then()
,从左到右依次执行函数组合。 函数的返回值,可以是:简单值、Promise
对象,或者可以定义为 async
,通过 wait
返回值。
const pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
const sum = pipeAsyncFunctions( x => x + 1, x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)), x => x + 3, async x => (await x) + 4 ); (async() => { console.log(await sum(5)); // 15 (after one second) })();
推荐资源- ES6:正确的部分
学习新的ES6 JavaScript语言特性,如箭头函数,解构,生成器和更多的编写更干净,更有效,可读的程序。
pipeFunctions
从左到右执行函数组合。
使用 Array.prototype.reduce()
和扩展操作符 (...
) 来执行从左到右的函数组合。 第一个(最左边)函数可以接受一个或多个参数;其余的函数只接受一个参数。
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
const add5 = x => x + 5; const multiply = (x, y) => x * y; const multiplyAndAdd5 = pipeFunctions(multiply, add5); multiplyAndAdd5(5, 2); // 15
promisify
将异步函数转换后,返回成 Promise
对象。
使用柯里化函数,返回调用原始函数的 Promise
对象。 使用的 ...rest
操作符传入所有参数。
在 Node 8+中,你可以使用 util.promisify
const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => (err ? reject(err) : resolve(result))) );
const delay = promisify((d, cb) => setTimeout(cb, d)); delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
rearg
创建一个函数,该函数调用提供的函数,并根据指定的索引排列参数。
使用 Array.prototype.map()
根据 indexes
和扩展操作符 (...
) 对参数重新排序,将转换后的参数传递给 fn
。
const rearg = (fn, indexes) => (...args) => fn(...indexes.map(i => args[i]));
var rearged = rearg( function(a, b, c) { return [a, b, c]; }, [2, 0, 1] ); rearged('b', 'c', 'a'); // ['a', 'b', 'c']
spreadOver
Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function.
Use closures and the spread operator (...
) to map the array of arguments to the inputs of the function.
接受一个可变参数的函数并返回一个闭包函数,该闭包函数接受要映射到函数的参数数组。
使用闭包和扩展操作符 (...
) 将参数数组一一映射为函数的参数。
const spreadOver = fn => argsArr => fn(...argsArr);
const arrayMax = spreadOver(Math.max); arrayMax([1, 2, 3]); // 3
unary
创建一个函数,该函数最多只接受一个参数,忽略其他的参数。
调用提供的函数 fn
,只需要给第一个参数即可。
const unary = fn => val => fn(val);
['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]