如何优化ES6+环境下类社交平台的相对时间显示函数?
Optimized
timeAgo Function Using ES6+ Features Great question! Your original code works as intended, but we can refactor it to be far cleaner, more maintainable, and easier to extend using modern JavaScript features. Let's align it with the clean, scalable logic used by platforms like YouTube, Facebook, and Instagram.
The Pain Points in the Original Code
- Repetitive calls to
date1.diff(unnecessary redundant calculations) - Hardcoded time thresholds that are hard to read and adjust
- A long chain of
ifstatements that's tedious to update if you ever want to modify or add time units
Refactored Solution
Here's the optimized version that fixes these issues while preserving your exact desired output:
const timeAgo = (createdOn) => { const now = dayjs(); const targetDate = dayjs(createdOn); // Optional: Validate input to avoid errors with invalid dates if (!targetDate.isValid()) return 'Invalid date'; const diffInSeconds = now.diff(targetDate, 'second'); // Centralize all time rules in a single, easy-to-edit array // Structure: [threshold (seconds), dayjs unit, display suffix] const timeUnits = [ { threshold: 365 * 24 * 60 * 60, unit: 'year', suffix: 'y' }, { threshold: 30 * 24 * 60 * 60, unit: 'month', suffix: 'm' }, { threshold: 7 * 24 * 60 * 60, unit: 'week', suffix: 'w' }, { threshold: 24 * 60 * 60, unit: 'day', suffix: 'd' }, { threshold: 60 * 60, unit: 'hour', suffix: 'h' }, { threshold: 60, unit: 'minute', suffix: 'm' }, ]; // Find the first time unit that matches our time difference const matchedUnit = timeUnits.find(unit => diffInSeconds >= unit.threshold); if (matchedUnit) { const value = now.diff(targetDate, matchedUnit.unit); return `${value}${matchedUnit.suffix} ago`; } // Fallback for times under 60 seconds return `${diffInSeconds}s ago`; };
Key Improvements
- Reusable Input: Instead of hardcoding
base.createdOn, we passcreatedOnas a parameter. This makes the function usable across different parts of your app, not just tied to one data source. - Centralized Configuration: All time thresholds, dayjs units, and display suffixes live in a single array. Want to adjust how months are calculated (e.g., use actual calendar months instead of 30 days)? Just update the
thresholdvalue in the array—no digging through nestedifstatements. - Single Calculation: We only compute
diffInSecondsonce, eliminating redundant work and making the code more efficient. - ES6
findMethod: Replaces the longifchain with a singlefindcall that grabs the first matching time unit. This makes the logic far easier to follow at a glance. - Template Literals: Uses
${value}${suffix}instead of string concatenation for cleaner, more readable output strings.
Optional Extra: Singular/Plural Support
If you ever want to expand to full words (e.g., 1 hour ago vs 2 hours ago), you can extend the timeUnits array with plural labels:
const timeUnits = [ { threshold: 365 * 24 * 60 * 60, unit: 'year', singular: 'year', plural: 'years' }, // ... other units ]; // Update the return logic: return `${value} ${value === 1 ? matchedUnit.singular : matchedUnit.plural} ago`;
But since your original requirement uses shorthand suffixes (y, m, etc.), this is entirely optional.
内容的提问来源于stack exchange,提问作者Ion Utale
相关产品推荐
相关产品推荐

