typescript - การเขียนฟังก์ชันเล็ก ๆ ที่ห่อด้วยตัวบันทึกใหม่โดยใช้ fp-ts
ฉันต้องการลองเขียนบางส่วนของโค้ดของฉันใหม่โดยใช้ fp-ts และพิจารณาที่จะปรับปรุงวิธีการดังต่อไปนี้:
export const createApiServer = () => {
logger.info("Starting World Server API");
const apiServer = express()
// 3rd party middleware
.use(helmet())
.use(bodyParser.json())
.use(cors())
// Root route
.get("/", (_, result) => result.sendStatus(httpStatusCodes.OK))
// 404 - Not Found
.use((_, result) => result.sendStatus(httpStatusCodes.NOT_FOUND))
// 500 - Internal Server Error
.use(errorLoggerMiddleware)
.use(errorResponseMiddleware);
logger.verbose(`Initialized World Server API in ${process.uptime().toFixed(3)} seconds`);
return apiServer;
};
หลังจากอ่านเกี่ยวกับประเภท IO สำหรับผลข้างเคียง ฉันพยายามใช้งานมันดังนี้:
const info = (message: string) => new IO(() => log.info(message));
const verbose = (message: string) => new IO(() => log.verbose(message));
const setupApiServer = () =>
new IO(() =>
express()
.use(helmet())
.use(bodyParser.json())
.use(cors())
.get("/", (_, result) => result.sendStatus(httpStatusCodes.OK))
.use((_, result) => result.sendStatus(httpStatusCodes.NOT_FOUND))
.use(errorLoggerMiddleware)
.use(errorResponseMiddleware)
);
export const createApiServer = () =>
info("Starting World Server API")
.chain(setupApiServer)
.chain((apiServer) =>
verbose(`Initialized World Server API in ${process.uptime().toFixed(3)} seconds`)
.map(() => apiServer)
)
.run();
มันรู้สึกค่อนข้างแปลกที่จะใช้วิธี map โดยไม่กำหนดไปยังอ็อบเจ็กต์ apiServer ในการเรียกเชนครั้งสุดท้ายเพียงเพื่อบันทึกระหว่างการรับและส่งต่อ ฉันอยากรู้ว่าสิ่งนี้ถูกต้องหรือมีรูปแบบอื่นสำหรับเรื่องนี้หรือไม่
คำตอบ #1
คุณสามารถใช้ chainFirst ได้
ด้วย chainFirst คุณสามารถปรับปรุงโค้ดนี้ได้
import { pipe } from "fp-ts/lib/pipeable";
import * as IO from "fp-ts/lib/IO";
declare const log: (m: string) => IO.IO<void>
declare const a: IO.IO<number>
pipe(
a,
IO.chain((a) => pipe(log(`Got ${a}`), IO.map(() => a)))
)
เข้าไปในนี้
pipe(
a,
IO.chainFirst((a) => log(`Got ${a}`))
)
