AI眼中的完美代码……
经过两个AI的来回指导和来回改善,这可能是最完美的代码了。
// TypeScript版本 interface Article { title: string; category: string; } class BlogArticles { private data: Article[]; private filteredData: Article[]; private cache: { [key: string]: Article[] }; /** * 构造函数,初始化文章数据。 * @param data - 文章数据数组。 */ constructor(data: Article[]) { if (!Array.isArray(data)) { throw new Error('Invalid data: expected an array of articles.'); } // 验证每个文章对象 for (const article of data) { if (typeof article.title !== 'string' || typeof article.category !== 'string') { throw new Error('Invalid article: each article must have a title and category.'); } } this.data = data; // 原始数据 this.filteredData = [...data]; // 使用扩展运算符复制数据 this.cache = {}; // 用于缓存过滤结果 } /** * 根据给定的标准筛选和分页数据。 * @param criteria - 筛选标准,包括category, page, pagesize。 * @returns 当前实例,支持链式调用。 */ filter(criteria: { category: string; page: number; pagesize: number }): this { const { category, page, pagesize } = criteria; if (typeof category !== 'string') { throw new Error('Invalid category: expected a string.'); } if (typeof page !== 'number' || page < 1) { throw new Error('Invalid page: expected a positive integer.'); } if (typeof pagesize !== 'number' || pagesize < 1) { throw new Error('Invalid pagesize: expected a positive integer.'); } const cacheKey = `${category}-${page}-${pagesize}`; if (this.cache[cacheKey]) { this.filteredData = this.cache[cacheKey]; } else { let filtered = this.data.filter(article => article.category === category); const start = (page - 1) * pagesize; const end = start + pagesize; this.filteredData = filtered.slice(start, end); this.cache[cacheKey] = this.filteredData; } return this; // 支持链式调用 } /** * 清除缓存。 * @returns 当前实例,支持链式调用。 */ clearCache(): this { this.cache = {}; return this; } /** * 更新或添加文章数据。 * @param newData - 新的文章数据数组。 * @returns 当前实例,支持链式调用。 */ updateData(newData: Article[]): this { if (!Array.isArray(newData)) { throw new Error('Invalid data: expected an array of articles.'); } // 验证每个文章对象 for (const article of newData) { if (typeof article.title !== 'string' || typeof article.category !== 'string') { throw new Error('Invalid article: each article must have a title and category.'); } } this.data = newData; // 更新原始数据 this.clearCache(); // 清除缓存 this.filteredData = [...newData]; // 更新筛选后的数据 return this; // 支持链式调用 } /** * 遍历筛选后的数据并执行回调函数。 * @param callback - 每个元素上执行的回调函数。 * @returns 当前实例,支持链式调用。 */ forEach(callback: (value: Article, index: number, array: Article[]) => void): this { if (typeof callback !== 'function') { throw new TypeError('Callback must be a function.'); } try { this.filteredData.forEach(callback); } catch (error) { console.error('Error in forEach callback:', error); } return this; // 支持链式调用 } /** * 对筛选后的数据进行排序。 * @param compareFn - 比较函数,类似于Array.prototype.sort()的参数。 * @returns 当前实例,支持链式调用。 */ sort(compareFn: (a: Article, b: Article) => number): this { if (typeof compareFn !== 'function') { throw new TypeError('Compare function must be a function.'); } this.filteredData.sort(compareFn); return this; // 支持链式调用 } /** * 执行回调函数,并保持链式调用的能力。 * @param callback - 要执行的回调函数。 * @returns 当前实例,支持链式调用。 */ execute(callback: () => void): this { if (typeof callback !== 'function') { throw new TypeError('Callback must be a function.'); } try { callback.call(this); // 使用当前实例作为上下文执行callback } catch (error) { console.error('Error in execute callback:', error); } return this; // 支持链式调用 } /** * 执行回调函数,但不返回当前实例(非链式调用)。 * @param callback - 要执行的回调函数。 */ executeOnce(callback: () => void): void { if (typeof callback !== 'function') { throw new TypeError('Callback must be a function.'); } try { callback.call(this); // 使用当前实例作为上下文执行callback } catch (error) { console.error('Error in executeOnce callback:', error); } } } // 示例使用 const xhrResponse = `[ {"title": "Article 1", "category": "JS"}, {"title": "Article 2", "category": "JS"}, {"title": "Article 3", "category": "CSS"} ]`; try { const blog = new BlogArticles(JSON.parse(xhrResponse)); blog .filter({ category: 'JS', page: 1, pagesize: 2 }) // 筛选JS类别的前两篇文章 .sort((a, b) => a.title.localeCompare(b.title)) // 按标题字母顺序排序 .forEach((value, index, array) => { // 遍历筛选后的数据,创建HTML结构 document.body.insertAdjacentHTML('beforeend', `<div>${value.title}</div>`); }) .execute(() => { // 执行一些后续操作,比如打印日志 console.log('第一页显示完成'); }) .execute(() => { // 调用Live2D的API(如果可用) Live2D?.getCurrentInstance()?.sayMessage('第一页'); }) .execute(() => { // 隐藏pace进度条(如果可用) pace?.hide?.(); }); } catch (error) { console.error('Error initializing BlogArticles:', error); } // 单元测试示例 if (typeof describe === 'function') { describe('BlogArticles', () => { it('should filter and paginate correctly', () => { const data: Article[] = [ { title: 'Article 1', category: 'JS' }, { title: 'Article 2', category: 'JS' }, { title: 'Article 3', category: 'CSS' } ]; const blog = new BlogArticles(data); blog.filter({ category: 'JS', page: 1, pagesize: 2 }); expect(blog.filteredData.length).toBe(2); expect(blog.filteredData[0].title).toBe('Article 1'); expect(blog.filteredData[1].title).toBe('Article 2'); }); it('should clear the cache', () => { const data: Article[] = [ { title: 'Article 1', category: 'JS' }, { title: 'Article 2', category: 'JS' } ]; const blog = new BlogArticles(data); blog.filter({ category: 'JS', page: 1, pagesize: 2 }); blog.clearCache(); expect(Object.keys(blog.cache).length).toBe(0); }); it('should sort the filtered data', () => { const data: Article[] = [ { title: 'B Article', category: 'JS' }, { title: 'A Article', category: 'JS' } ]; const blog = new BlogArticles(data); blog.filter({ category: 'JS', page: 1, pagesize: 2 }).sort((a, b) => a.title.localeCompare(b.title)); expect(blog.filteredData[0].title).toBe('A Article'); expect(blog.filteredData[1].title).toBe('B Article'); }); it('should handle errors in forEach and execute methods', () => { const data: Article[] = [ { title: 'Article 1', category: 'JS' }, { title: 'Article 2', category: 'JS' } ]; const blog = new BlogArticles(data); // 测试 forEach 方法中的错误处理 const originalConsoleError = console.error; console.error = jest.fn(); blog.forEach((value, index, array) => { if (index === 1) { throw new Error('Test error in forEach'); } }); expect(console.error).toHaveBeenCalled(); // 测试 execute 方法中的错误处理 blog.execute(() => { throw new Error('Test error in execute'); }); expect(console.error).toHaveBeenCalledTimes(2); console.error = originalConsoleError; }); }); }
最新回复 ( 0 )
目录
无
Geticer
管理员组
主题数 23 |
帖子数 2 |
0 精华数 |