函数 声明式编程

22 阅读1分钟
const oneSecond = () => 1000;
const getCurrentTime = () => new Date();
const clear = () => console.clear();
const log = message => console.log(message);
const setIntervalFn = (interval) =>
    (fn) => window.setInterval(fn, interval);
const compose = (...fns) => (arg) =>
    fns.reduce((composed, f) => f(composed), arg);


const serializeTime = data => ({
    hours: data.getHours(),
    minutes: data.getMinutes(),
    seconds: data.getSeconds(),
})

const appendAMPM = clockTime => ({
    ...clockTime,
    ampm: clockTime.hours >= 12 ? 'PM' : 'AM'
})

const civilianHours = clockTime => ({
    ...clockTime,
    hours: (clockTime.hours > 12) ? clockTime.hours - 12 : clockTime.hours
})

const display = target => clockTime => target(clockTime)

const formatClock = template => clockTime =>
    template
        .replace('hh', clockTime.hours)
        .replace('mm', clockTime.minutes)
        .replace('ss', clockTime.seconds)
        .replace('tt', clockTime.ampm)

const prependZero = (key) => (clockTime) => ({
    ...clockTime,
    [key]: clockTime[key] < 10 ? '0' + clockTime[key] : clockTime[key]
})

const convertToCivilianTime = clockTime => compose(
    appendAMPM,
    civilianHours
)(clockTime);

const doubleDigits = clockTime => compose(
    prependZero('hours'),
    prependZero('minutes'),
    prependZero('seconds')
)(clockTime);

const ticking = () => compose(
    clear,
    getCurrentTime,
    serializeTime,
    convertToCivilianTime,
    doubleDigits,
    formatClock('hh:mm:ss tt'),
    display(log),
)

start = () => compose(
    ticking,
    setIntervalFn(oneSecond()),
)()

start();