首先使用 fp-ts 库进入 typescript 函数式编程的世界。
我在这里有一个埃及人会引以为豪的“末日金字塔”,我的方法显然做错了。我应该采取什么方法以一种不太命令的方式解决我的嵌套数据获取问题?
金字塔
export const getProgramWithAllElements = (programId: FirestoreDocumentId): TE.TaskEither<FirestoreError, Program> =>
pipe(
getProgram(programId),
TE.chain((program) =>
pipe(
getCollCollectionsFromPath(program.id),
TE.chain((collections) =>
pipe(
collections,
A.map((collection) =>
pipe(
getWeekCollectionsFromPath(program.id)(collection.id),
TE.chain((weeks) =>
pipe(
weeks,
A.map((week) =>
pipe(
getDayCollectionsFromPath(program.id)(collection.id)(week.id),
TE.chain((days) =>
pipe(
days,
A.map((day) =>
pipe(
getExerciseCollectionsFromPath(program.id)(collection.id)(week.id)(day.id),
TE.map(
(exercises) =>
({
...day,
exercises: exercises,
} as Day)
)
)
),
A.sequence(TE.taskEither)
)
),
TE.map(
(days) =>
({
...week,
days: days,
} as Week)
)
)
),
A.sequence(TE.taskEither)
)
),
TE.map(
(weeks) =>
({
...collection,
weeks: weeks,
} as Collection)
)
)
),
A.sequence(TE.taskEither)
)
),
TE.map(
(collections) =>
({
...program,
collections: collections,
} as Program)
)
)
)
);
片段中使用的函数
declare const getProgram: (programId: FirestoreDocumentId) => TE.TaskEither<FirestoreError, Program>;
declare const getCollCollectionsFromPath: (
programId: FirestoreDocumentId
) => TE.TaskEither<FirestoreError, Collection[]>;
declare const getWeekCollectionsFromPath: (
programId: FirestoreDocumentId
) => (collectionId: FirestoreDocumentId) => TE.TaskEither<FirestoreError, Week[]>;
declare const getDayCollectionsFromPath: (programId: FirestoreDocumentId) => (collectionId: FirestoreDocumentId) => (
weekId: FirestoreDocumentId
) => TE.TaskEither<FirestoreError, Day[]>;
declare const getExerciseCollectionsFromPath: (programId: FirestoreDocumentId) => (collectionId: FirestoreDocumentId) => (
weekId: FirestoreDocumentId
) => (dayId: FirestoreDocumentId) => TE.TaskEither<FirestoreError, Exercise[]>;
简化数据模型
export interface Program {
id: string;
// Other Fields
collections?: Collection[];
}
export interface Collection {
id: string;
// Other Fields
weeks?: Week[];
}
export interface Week {
id: string;
// Other Fields
days?: Day[];
}
export interface Day {
id: string;
// Other Fields
exercises: ProgramExercise[];
}
export interface ProgramExercise {
id: string;
// Other Fields
}