Skip to content

Curry 柯里化

chain(链)

创建一个按顺序运行的函数链

基本用法

链接函数将导致它们依次执行,将每个函数的输出作为下一个函数的输入传递,最终在链的末尾返回最终输出。

ts
import { chain } from "radash";

const add = (y: number) => (x: number) => x + y;
const mult = (y: number) => (x: number) => x * y;
const addFive = add(5);
const double = mult(2);

const chained = chain(addFive, double);

chained(0); // => 10
chained(7); // => 24

例子

ts
import { chain } from "radash";

type Deity = {
  name: string;
  rank: number;
};

const gods: Deity[] = [
  { rank: 8, name: "Ra" },
  { rank: 7, name: "Zeus" },
  { rank: 9, name: "Loki" },
];

const getName = (god: Deity) => item.name;
const upperCase = (text: string) => text.toUpperCase() as Uppercase<string>;

const getUpperName = chain(getName, upperCase);

getUpperName(gods[0]); // => 'RA'
gods.map(getUpperName); // => ['RA', 'ZEUS', 'LOKI']

compose(组合)

创建函数的组合

基本用法

在函数的组合中,每个函数都将下一个函数作为参数,并必须调用它以继续执行。

ts
import { compose } from "radash";

const useZero = (fn: any) => () => fn(0);
const objectize = (fn: any) => (num: any) => fn({ num });
const increment =
  (fn: any) =>
  ({ num }: any) =>
    fn({ num: num + 1 });
const returnArg = (arg: any) => (args: any) => args[arg];

const composed = compose(
  useZero,
  objectize,
  increment,
  increment,
  returnArg("num")
);

composed(); // => 2

这可能会有点令人震惊,如果你以前没见过的话。这是一个分解的组成部分。它相当于上面的代码。

ts
const decomposed = useZero(objectize(increment(increment(returnArg("num")))));

decomposed(); // => 2

debounce(防抖)

创建一个防抖回调函数

基本用法

防抖接受一个选项对象,其中包含一个 delay 和一个源函数,在调用时调用。当调用返回的函数时,它将在 delay 毫秒的时间过去后才调用源函数。不会导致调用源函数的调用会重置延迟,推迟下一次调用。

ts
import { debounce } from "radash";

const makeSearchRequest = (event) => {
  api.movies.search(event.target.value);
};

input.addEventListener("change", debounce({ delay: 100 }, makeSearchRequest));

Timing 时间控制

delay100 时,形象地显示了防抖行为。由 debounce 返回的防抖函数可以每毫秒调用一次,但只有在经过 delay 毫秒后才会调用指定的回调函数。

sh
                Time: 0ms - - - - 100ms - - - - 200ms - - - - 300ms - - - - 400ms - - - -
debounce Invocations: x x x x - - - - - - - - x x x x x x x x x x - - - - - - - - - - - -
  Source Invocations: - - - - - - - - - - x - - - - - - - - - - - - - - - - - x - - - - -

Cancel 取消

debounce 返回的函数具有 cancel 方法,当调用时将永久停止源函数被防抖。

ts
const debounced = debounce({ delay: 100 }, api.feed.refresh);

// ... sometime later

debounced.cancel();

Flush 清空

debounce 返回的函数具有一个 flush 方法,当调用时,将直接调用源函数。

ts
const debounced = debounce({ delay: 100 }, api.feed.refresh);

// ... sometime later

debounced.flush(event);

isPending 正在等待

debounce 返回的函数具有 isPending 方法,当调用时将返回源函数中是否有任何挂起的调用。

ts
const debounced = debounce({ delay: 100 }, api.feed.refresh);

// ... sometime later

debounced.isPending();

memo(备忘录)

记忆化一个函数

基本用法

使用 memo 对函数进行包装,然后得到一个自动返回已经计算过的值的函数。

ts
import { memo } from "radash";

const timestamp = memo(() => Date.now());

const now = timestamp();
const later = timestamp();

now === later; // => true

Expiration 过期

您可以选择性地传递一个 ttl(生存时间)参数,以便在存储的结果过期时失效。在 10 版本之前的版本中,如果未指定, ttl 的值为 300 毫秒。

ts
import { memo, sleep } from "radash";

const timestamp = memo(() => Date.now(), {
  ttl: 1000, // milliseconds
});

const now = timestamp();
const later = timestamp();

await sleep(2000);

const muchLater = timestamp();

now === later; // => true
now === muchLater; // => false

Key Function

您可以选择自定义缓存时存储值的方式。

ts
const timestamp = memo(
  ({ group }: { group: string }) => {
    const ts = Date.now();
    return `${ts}::${group}`;
  },
  {
    key: ({ group }: { group: string }) => group,
  }
);

const now = timestamp({ group: "alpha" });
const later = timestamp({ group: "alpha" });
const beta = timestamp({ group: "beta" });

now === later; // => true
beta === now; // => false

partial(部分)

创建一个部分函数

基本用法

通过提供所需函数的一些或全部参数来创建一个部分函数。

ts
import { partial } from "radash";

const add = (a: number, b: number) => a + b;

const addFive = partial(add, 5);

addFive(2); // => 7

partob()

创建一个 partob 函数

基本用法

现代 JavaScript 解构意味着许多开发人员、库和框架都选择了取一个包含参数的单一对象的一元函数。 _.partob 函数让你分解这些一元函数。

ts
import { partob } from "radash";

const add = (props: { a: number; b: number }) => props.a + props.b;

const addFive = partob(add, { a: 5 });

addFive({ b: 2 }); // => 7

proxied(代理)

创建一个动态代理对象

基本用法

JavaScript 的 Proxy 对象功能强大,但使用起来有些笨拙。 _.proxied 函数为您创建 Proxy ,并在 Proxy 上调用函数或访问属性时处理调用回到您的处理程序。

ts
import { proxied } from 'radash'

type Property = 'name' | 'size' | 'getLocation'

const person = proxied((prop: Property) => {
  switch (prop) {
    case 'name':
      return 'Joe'
    case 'size':
      return 20
    case 'getLocation'
      return () => 'here'
  }
})

person.name // => Joe
person.size // => 20
person.getLocation() // => here

throttle(节流)

创建一个节流的回调函数

基本用法

节流函数接受一个带有 interval 和源函数的选项对象,在调用时会调用源函数。当调用返回的函数时,只有在 interval 毫秒的时间经过后才会调用源函数。否则,它将忽略调用。

ts
import { throttle } from "radash";

const onMouseMove = () => {
  rerender();
};

addEventListener("mousemove", throttle({ interval: 200 }, onMouseMove));

Timing 时间控制

interval200 时,节流行为的可视化。由 throttle 返回的节流函数可以每毫秒调用一次,但只有在经过 interval 毫秒后才会调用给定的回调函数。

sh
                Time: 0ms - - - - 100ms - - - - 200ms - - - - 300ms - - - - 400ms - - - -
Throttle Invocations: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x - - -
  Source Invocations: x - - - - - - - - - - - - x - - - - - - - - - - - - - x - - - - - -

isThrottled 被限制

throttle 返回的函数具有一个 isThrottled 方法,当调用时,将返回是否存在任何活跃的节流。

ts
const debounced = throttle({ interval: 200 }, onMouseMove);

// ... sometime later

debounced.isThrottled();