Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions benchmarks/bundle-size/fp/flowAsync.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from 'vitest';
import { getBundleSizeFromScript } from '../utils/getBundleSize';

describe('fp/flowAsync bundle size', () => {
it('es-toolkit/fp', async () => {
expect(
await getBundleSizeFromScript('import { flowAsync } from "es-toolkit/fp"; console.log(flowAsync)')
).toMatchInlineSnapshot(`194`);
});
});
66 changes: 66 additions & 0 deletions docs/fp/reference/flowAsync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# flowAsync (Functional Programming)

Performs left-to-right async function composition, returning a reusable async function that awaits every intermediate result.

```typescript
const fn = flowAsync(...functions);
const result = await fn(...args);
```

::: info

`flowAsync` is the promise-aware sibling of [`flow`](./flow.md). `flow` passes each raw return value straight to the next function, so a returned `Promise` arrives unresolved; `flowAsync` awaits every step, letting synchronous and asynchronous functions mix freely in one chain.

:::

## Usage

`flowAsync` takes a sequence of functions and composes them left-to-right into a single async function. The first function may take any number of arguments; every later function is unary and receives the awaited result of the previous one. The composed function always returns a `Promise`.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const fetchUser = async (id: number) => ({ id, name: 'Alice' });
const getName = (user: { name: string }) => user.name;

const getUserName = flowAsync(fetchUser, getName);

await getUserName(1); // => 'Alice'
```

Synchronous and asynchronous functions can be mixed in any order; each result is awaited before it is passed on.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const process = flowAsync(
(x: number) => x + 1,
async x => x * 3,
x => `value: ${x}`
);

await process(1); // => 'value: 6'
```

If any function throws or returns a rejected `Promise`, the composed function rejects with that error, so a single `try`/`catch` (or `.catch`) around the call handles failures from every step.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const risky = flowAsync(
async (id: number) => {
throw new Error(`user ${id} not found`);
},
(user: { name: string }) => user.name
);

await risky(1); // rejects with Error: user 1 not found
```

#### Parameters

- `functions`: The functions to compose, from left to right. The first may take any number of arguments; the rest are unary, each receiving the awaited output of the previous function.

#### Returns

A new async function that applies every function in sequence, awaiting each result. It accepts the same parameters as the first function and resolves to the awaited result of the last. The public overloads infer the precise types from the chain.
66 changes: 66 additions & 0 deletions docs/ja/fp/reference/flowAsync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# flowAsync (関数型プログラミング)

左から右へ関数を非同期に合成し、各中間結果を待機する再利用可能な非同期関数を返します。

```typescript
const fn = flowAsync(...functions);
const result = await fn(...args);
```

::: info

`flowAsync` は [`flow`](./flow.md) の Promise 対応版です。`flow` は各関数の戻り値をそのまま次の関数に渡すため、`Promise` を返すと未解決のまま渡されてしまいます。`flowAsync` はすべてのステップを待機するため、同期関数と非同期関数を 1 つのチェーンで自由に混在させられます。

:::

## 使用法

`flowAsync` は一連の関数を受け取り、左から右へ 1 つの非同期関数に合成します。最初の関数は任意の数の引数を受け取れますが、それ以降の関数はすべて単項で、直前の関数の結果を待機した値を受け取ります。合成された関数は常に `Promise` を返します。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const fetchUser = async (id: number) => ({ id, name: 'Alice' });
const getName = (user: { name: string }) => user.name;

const getUserName = flowAsync(fetchUser, getName);

await getUserName(1); // => 'Alice'
```

同期関数と非同期関数は任意の順序で混在できます。各結果は次の関数に渡される前に待機されます。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const process = flowAsync(
(x: number) => x + 1,
async x => x * 3,
x => `value: ${x}`
);

await process(1); // => 'value: 6'
```

いずれかの関数がエラーを投げたり、拒否された `Promise` を返したりすると、合成された関数もそのエラーで拒否されます。呼び出しを 1 つの `try`/`catch`(または `.catch`)で囲めば、すべてのステップの失敗を処理できます。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const risky = flowAsync(
async (id: number) => {
throw new Error(`user ${id} not found`);
},
(user: { name: string }) => user.name
);

await risky(1); // Error: user 1 not found で拒否されます。
```

#### パラメータ

- `functions`: 左から右へ合成する関数です。最初の関数は任意の数の引数を受け取れますが、残りはすべて単項で、直前の関数の出力を待機した値を受け取ります。

#### 戻り値

すべての関数を順番に適用し、各結果を待機する新しい非同期関数です。最初の関数と同じパラメータを受け取り、最後の関数の結果を待機した値で解決されます。公開されているオーバーロードは、チェーンから正確な型を推論します。
66 changes: 66 additions & 0 deletions docs/ko/fp/reference/flowAsync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# flowAsync (함수형 프로그래밍)

왼쪽에서 오른쪽으로 함수를 비동기로 합성해서, 매 중간 결과를 기다리는 재사용 가능한 비동기 함수를 반환해요.

```typescript
const fn = flowAsync(...functions);
const result = await fn(...args);
```

::: info

`flowAsync`는 [`flow`](./flow.md)의 Promise 인식 버전이에요. `flow`는 각 함수의 반환값을 그대로 다음 함수에 넘기기 때문에, 어떤 함수가 `Promise`를 반환하면 `await`되지 않은 상태로 다음 함수에 전달돼요. `flowAsync`는 매 단계를 기다려서, 동기 함수와 비동기 함수를 한 체인에서 자유롭게 섞어 쓸 수 있어요.

:::

## 사용법

`flowAsync`는 여러 함수를 받아서 왼쪽에서 오른쪽으로 하나의 비동기 함수로 합성해요. 첫 번째 함수는 인자를 몇 개든 받을 수 있고, 그 뒤의 함수들은 모두 인자를 하나 받아서 이전 함수의 결과를 기다린 값을 넘겨받아요. 합성된 함수는 항상 `Promise`를 반환해요.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const fetchUser = async (id: number) => ({ id, name: 'Alice' });
const getName = (user: { name: string }) => user.name;

const getUserName = flowAsync(fetchUser, getName);

await getUserName(1); // => 'Alice'
```

동기 함수와 비동기 함수를 어떤 순서로든 섞을 수 있어요. 각 결과는 다음 함수로 넘어가기 전에 기다려져요.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const process = flowAsync(
(x: number) => x + 1,
async x => x * 3,
x => `value: ${x}`
);

await process(1); // => 'value: 6'
```

어떤 함수든 에러를 던지거나 거부된 `Promise`를 반환하면, 합성된 함수도 그 에러로 거부돼요. 호출부를 `try`/`catch`(또는 `.catch`) 하나로 감싸면 모든 단계의 실패를 처리할 수 있어요.

```typescript
import { flowAsync } from 'es-toolkit/fp';

const risky = flowAsync(
async (id: number) => {
throw new Error(`user ${id} not found`);
},
(user: { name: string }) => user.name
);

await risky(1); // Error: user 1 not found 로 거부돼요.
```

#### 파라미터

- `functions`: 왼쪽에서 오른쪽으로 합성할 함수들이에요. 첫 번째 함수는 인자를 몇 개든 받을 수 있고, 나머지는 모두 인자를 하나 받아서 이전 함수의 출력을 기다린 값을 넘겨받아요.

#### 반환 값

모든 함수를 순서대로 적용하면서 각 결과를 기다리는 새로운 비동기 함수예요. 첫 번째 함수와 같은 파라미터를 받아서 마지막 함수의 결과를 기다린 값으로 해결돼요. 공개된 오버로드는 체인에서 정확한 타입을 추론해요.
66 changes: 66 additions & 0 deletions docs/zh_hans/fp/reference/flowAsync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# flowAsync (函数式编程)

执行从左到右的异步函数组合,返回一个会等待每个中间结果的可复用异步函数。

```typescript
const fn = flowAsync(...functions);
const result = await fn(...args);
```

::: info

`flowAsync` 是 [`flow`](./flow.md) 的 Promise 感知版本。`flow` 会将每个函数的原始返回值直接传给下一个函数,因此返回的 `Promise` 会以未解决的状态被传递;`flowAsync` 会等待每一步,让同步函数和异步函数可以在一条链中自由混用。

:::

## 用法

`flowAsync` 接收一系列函数,并将它们从左到右组合成一个异步函数。第一个函数可以接收任意数量的参数,其后的每个函数都是一元的,接收上一个函数结果被等待后的值。组合出的函数始终返回 `Promise`。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const fetchUser = async (id: number) => ({ id, name: 'Alice' });
const getName = (user: { name: string }) => user.name;

const getUserName = flowAsync(fetchUser, getName);

await getUserName(1); // => 'Alice'
```

同步函数和异步函数可以以任意顺序混用;每个结果在传给下一个函数之前都会被等待。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const process = flowAsync(
(x: number) => x + 1,
async x => x * 3,
x => `value: ${x}`
);

await process(1); // => 'value: 6'
```

如果任何函数抛出错误或返回被拒绝的 `Promise`,组合出的函数就会以该错误拒绝。只需在调用处使用一个 `try`/`catch`(或 `.catch`),就能处理每一步的失败。

```typescript
import { flowAsync } from 'es-toolkit/fp';

const risky = flowAsync(
async (id: number) => {
throw new Error(`user ${id} not found`);
},
(user: { name: string }) => user.name
);

await risky(1); // 以 Error: user 1 not found 拒绝
```

#### 参数

- `functions`: 从左到右组合的函数。第一个函数可以接收任意数量的参数,其余函数都是一元的,接收上一个函数输出被等待后的值。

#### 返回值

一个依次应用所有函数并等待每个结果的新异步函数。它接收与第一个函数相同的参数,并解决为最后一个函数结果被等待后的值。公开的重载会从整条链中推断出精确的类型。
Loading
Loading