资讯专栏INFORMATION COLUMN

【30秒一个知识点】Adapter

邹立鹏 / 2229人阅读

摘要:给定一个函数,返回一个闭包,该闭包将所有输入收集到一个数组接受函数中。返回一个可变参数的闭包,在应用其他参数前,先把第一个以外的其他参数作为第一个参数。

本系列翻译自开源项目 30-seconds-of-code

这是一个非常优秀的系列,文章总结了大量的使用es6语法实现的代码模块不是说真的三十秒就能理解,也需要你认真的思考,其中有一些点非常精妙,很值得一读。

本文在我的github同步更新,你可以看到当前翻译的全部系列。

如果您对本期有不同或者更好的见解,请在下方评论告,喜欢请点个赞,谢谢阅读。

ary

创建一个可以接收n个参数的函数, 忽略其他额外的参数。

调用提供的函数fn,参数最多为n个, 使用 Array.prototype.slice(0,n) 和展开操作符 (...)。

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

将一个接收数组参数的函数改变为可变参数的函数。

给定一个函数,返回一个闭包,该闭包将所有输入收集到一个数组接受函数中。

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

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()transforms应用于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的组合,也可以定义为通过await返回的async值。
所有函数必须是一元的。

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)
})();
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
使用的...操作符来传入所有参数。

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

接受一个可变参数函数并返回一个闭包,该闭包接受一个参数数组以映射到函数的输入。

使用闭包和扩展操作符()将参数数组映射到函数的输入。

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]
推荐阅读

【React深入】setState的执行机制

【React深入】React事件机制

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102447.html

相关文章

  • 开发NEO智能合约的步骤流程

    摘要:在社区开发的一些最新工具集的帮助下,出现了四步流程法,从而进一步加快了开发效率。两步流程法传统上来说,智能合约开发有两步开发流程编码和测试。四步工作流程法开发智能合约对于编辑和调试阶段,我建议使用两种方法和。 摘要:开发NEO智能合约的典型开发流程有两个实际阶段:编码(在IDE中编码并将源码编译为.avm文件)以及测试(在测试网上部署、调用、检查结果)。这个工作流需要编译和部署来调试任...

    I_Am 评论0 收藏0
  • 开发NEO智能合约的步骤流程

    摘要:在社区开发的一些最新工具集的帮助下,出现了四步流程法,从而进一步加快了开发效率。两步流程法传统上来说,智能合约开发有两步开发流程编码和测试。四步工作流程法开发智能合约对于编辑和调试阶段,我建议使用两种方法和。 摘要:开发NEO智能合约的典型开发流程有两个实际阶段:编码(在IDE中编码并将源码编译为.avm文件)以及测试(在测试网上部署、调用、检查结果)。这个工作流需要编译和部署来调试任...

    zhou_you 评论0 收藏0
  • 一个轻量级 Python 装饰器的缓存库——wrapcache

    摘要:自己因为经常遇到这种场景,所以将其封装成一个库,方便使用。如何使用使用简单,只需要要在方法上面加一个装饰器即可缓存,并且设置缓存过期时间。以上即可,第一次运行需要秒,第二次运行过期时间秒之内瞬间给出缓存结果。适合于小场景的方法缓存。 A python Function / Method OUTPUT cache system base on function Decorators. 基...

    马永翠 评论0 收藏0
  • 一个轻量级 Python 装饰器的缓存库——wrapcache

    摘要:自己因为经常遇到这种场景,所以将其封装成一个库,方便使用。如何使用使用简单,只需要要在方法上面加一个装饰器即可缓存,并且设置缓存过期时间。以上即可,第一次运行需要秒,第二次运行过期时间秒之内瞬间给出缓存结果。适合于小场景的方法缓存。 A python Function / Method OUTPUT cache system base on function Decorators. 基...

    gekylin 评论0 收藏0
  • 30-seconds-code——adapter

    摘要:英文文章来源于给定一个键值和一组参数,但给定一个上下文时调用它们。 英文文章来源于:https://github.com/Chalarangelo/30-seconds-of-code/blob/master/README.md Adapter call 给定一个键值和一组参数,但给定一个上下文时调用它们。 使用闭包调用存储的键值与存储的参数 const call = ( key, ....

    dcr309duan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<