第192天:js---Date对象属性和方法总结

本文介绍了JavaScript中日期对象的构造方法及日期时间的获取与设置技巧,包括四种构造函数重载方式、日期对象转字符串及字符串转日期对象的方法。

日期对象构造函数重载方法

一,第一种重载方法---基本当前时间

 1 //构造函数 - 第一种重载方法:基本 当前时间
 2 console.log('构造函数 - 第一种重载方法:基本 当前时间')
 3 date = new Date(); //返回时间对象 以调用getDate(),内容为当前时间
 4 console.log(date); //Sat Mar 10 2018 22:04:38 GMT+0800 (中国标准时间)
 5 
 6 date = Date(); //返回时间字符串 没有getDate等日期对象方法,内容为当前时间
 7 console.log(date); //Sat Mar 10 2018 22:04:38 GMT+0800 (中国标准时间)
 8 
 9 date = new Date(); //返回时间毫秒数字
10 console.log(date);
11 //一个静态方法 返回当前时间与1970-01-01的时间间隔,毫秒单位
12 console.log('静态方法')
13 console.log(Date.now());  //1520690678304

二,第二种重载 - 传递毫秒值

1 //构造函数 - 第二种重载 - 传递毫秒值
2 console.log('构造函数 - 第二种重载 - 传递毫秒值')
3 //距离起始时间1970年1月1日的毫秒数
4 date = new Date(1520690678304);
5 console.log(date.toLocaleString()); //2018/3/10 下午10:04:38

三,第三种重载 - 传递零散的年月日时间等日期时间参数

 1 //构造函数 - 第三种重载 - 传递零散的年月日时间等日期时间参数
 2 console.log('构造函数 - 第三种重载 - 传递零散的年月日时间等日期时间参数')
 3 /*  分散的时间数值型构造函数  -  构造函数有 2-7 个参数时, 将是根据 "年, 月, 日, 时, 分, 秒, 毫秒" 建立时间 */
 4 date = new Date(2018, 2, 10, 22, 59, 59);
 5 console.log(date.toLocaleString()); //2018/3/10 下午10:59:59
 6 
 7 date = new Date(2018, 2, 10, 22, 59);
 8 console.log(date.toLocaleString()); //2018/3/10 下午10:59:00
 9 
10 date = new Date(2018, 2, 10, 22);
11 console.log(date.toLocaleString()); //2018/3/10 下午10:00:00
12 
13 date = new Date(2018, 2, 10);
14 console.log(date.toLocaleString()); //2018/3/10 上午12:00:00
15 
16 date = new Date(2018, 2);
17 console.log(date.toLocaleString()); //2018/3/1 上午12:00:00

四,第四种重载---传递一个日期形式的字符串

 1 console.log('构造函数 - 第四种重载 - 传递一个日期形式的字符串')
 2 //date = new Date("month dd,yyyy hh:mm:ss");
 3 //date = new Date(yyyy,mth,dd);
 4 //month:用英文表示月份名称,从January到December
 5 //mth:用整数表示月份,从(1月)到11(12月)
 6 //dd:表示一个月中的第几天,从1到31
 7 //yyyy:四位数表示的年份
 8 //hh:小时数,从0(午夜)到23(晚11点)
 9 //mm:分钟数,从0到59的整数
10 //ss:秒数,从0到59的整数
11 date  = new Date("March 10, 2018 22:59:59"); //month dd,yyyy hh:mm:ss格式
12 console.log(date);                              //Sat Mar 10 2018 22:59:59 GMT+0800 (中国标准时间)
13 console.log(date.toLocaleString());             //2018/3/10 下午10:59:59
14 
15 date  = new Date("March 10,2018");            //month dd,yyyy格式
16 console.log(date);                               //Sat Mar 10 2018 00:00:00 GMT+0800 (中国标准时间)
17 console.log(date.toLocaleString());             //2018/3/10 上午12:00:00

五,将日期对象转换成字符串

1 /*将日期对象转换成字符串*/
2 
3 //转换成本地格式 -- 智能识别操作系统语言设置或者浏览器语言设置
4 console.log('转化成本地格式')
5 date = new Date();
6 console.log(date.toString())           //转换为字符串 Sun Mar 11 2018 09:17:15 GMT+0800 (中国标准时间)
7 console.log(date.toLocaleTimeString())  //获取当前时间        上午9:17:15
8 console.log(date.toLocaleDateString())  //获取当前日期        2018/3/11
9 console.log(date.toLocaleString())      //获取当前日期与时间  2018/3/11 上午9:17:15

六,将一个字符串转换为日期对象的写法

 1 /*将一个字符串转换为Date对象的写法*/
 2 
 3 //为什么需要将其转换成Date对象:因为我如果需要获取日期,或者设置日期时间等都需要在对象的基础上
 4 
 5 console.log('将一个字符串转换为Date对象的写法 -构造函数重载4方法')
 6 
 7 
 8 //方法1  构造函数重载4
 9 var str = "2018-3-11";
10 date  = new Date(str);  //字符串转换为Date对象
11 console.log(date.toLocaleString()); //2018/3/11 上午12:00:00
12 
13 
14 //方法2 Date.parse
15 console.log('将一个字符串转换为Date对象的写法 -Date.parse方法')
16 //把字符串转换为Date对象
17 //然后返回此Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
18 date = Date.parse("March 11, 2018")
19 console.log(date);//1520697600000
20 
21 date = "2018-3-11";
22 console.log(Date.parse(date));//1520697600000
23 //将字符串包装成对象之后,我们就可以使用接下来该对象拥有的属性和方法了。。。
24 date = new Date();
25 console.log(date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate());//2018-3-11  

七,获取具体的某个日期或者时间

 1 /*获取具体的某个日期或者时间*/
 2 
 3 //当使用构造函数实例化一个日期对象之后,接下来我们可以从其中获取具体的日期,时间等各种数字
 4 
 5 //获取日期 -  年(1970-????) 月(0-11) 日(0-31) 星期(0-6)
 6 console.log('获取日期')
 7 date = new Date();
 8 console.log(date.getFullYear());  //2018  获取完整的年份(4位,1970-????)
 9 console.log(date.getMonth()+1)     //3  获取当前月份(0-11,0代表1月),所以加1,就显示正常月份
10 console.log(date.getDate());   //11  获取几号   - 0 - 31 比如25
11 console.log(date.getDay());    //0 (0表示星期天)获取星期几 - 比如星期3的3
12 
13 
14 //获取时间 - 小时(0-23)  分(0-59)  秒(0-659) 毫秒值(0-999)  比如:12:23:45 375
15 console.log('获取时间')
16 date = new Date();
17 console.log(date.getHours())            //获取小时   9
18 console.log(date.getMinutes());         //获取分     31
19 console.log(date.getSeconds());         //获取秒   44
20 console.log(date.getMilliseconds());  // 获取毫秒  277
21 console.log(date.getTime());          // 获取相对于1970-01-01的毫秒值   1520731904277

八,设置具体的某个日期或者时间

 1 /*设置具体的某个日期或者时间*/
 2 
 3 //使用方法:创建一个日期对象,然后自定义具体的日期,时间
 4 
 5 //setFullYear(year, opt_month, opt_date) :设置Date对象的年份值;4位年份。
 6 //setMonth(month, opt_date) :设置Date对象的月份值。0表示1月,11表示12月。
 7 //setDate(date) :设置Date对象的月份中的日期值;值的范围1~31 。
 8 //setHours(hour, opt_min, opt_sec, opt_msec) :设置Date对象的小时值。
 9 //setMinutes(min, opt_sec, opt_msec) :设置Date对象的分钟值。
10 //setSeconds(sec, opt_msec) :设置Date对象的秒数值。
11 //setMilliseconds(msec) :设置Date对象的毫秒值。
12 
13 
14 //比如根据太阳的衰变动态计算太阳消失的时间
15 
16 date = new Date();
17 date.setFullYear(2020); // => 2020年
18 date.setMonth(1); // => 1:月;实际为2月份(月份从0开始计算)
19 date.setDate(20); // => 20:日
20 date.setHours(10); // => 10:时
21 date.setMinutes(30); // => 30:分
22 date.setSeconds(50); // => 50:秒
23 date.setMilliseconds(666); // => 666:毫秒
24 console.log(date); // =>  Thu Feb 20 2020 10:30:50 GMT+0800 (中国标准时间)

 

// 解析数据引用关系的辅助函数 /** * 解析数据中的引用关系 * 该函数用于处理嵌套的数据结构,将数据中的引用关系解析为实际的对象引用。 * 它会遍历数据中的所有实体,查找属性名中包含的数字(如"item1"), * 并尝试将这些属性值替换为对应类型数据中的实际对象引用。 * @param {Object} data - 包含嵌套引用的原始数据对象 * @returns {Object} 处理后的数据对象,其中引用已被解析为实际对象 */ function resolveDataReferences(data) { const keys = Object.keys(data); for (const key of keys) { const entities = data[key]; for (const entity of entities) { for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { // 修复:统一使用复数形式查找引用类型 let refType = attribute.replace(/\d/g, ''); // 尝试直接查找复数形式 if (!data[refType] && data[`${refType}s`]) { refType = `${refType}s`; } if (Array.isArray(entity[attribute])) { entity[attribute] = entity[attribute].map(item => data[refType]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { entity[attribute] = data[refType]?.find(updateItem => updateItem.id === entity[attribute].id) || entity[attribute]; } } } } } return data; } // 解析单个实体的数据引用 /** * 解析数据引用关系 * 该函数用于处理实体对象与数据源之间的引用关系,自动匹配并更新实体中的引用字段。 * @param {Object} entity - 需要处理的实体对象 * @param {Object} data - 包含引用数据的数据源对象 * @returns {Object} 处理后的实体对象 * 功能说明: * 遍历实体对象的每个属性 * 如果属性值是数组,则尝试在数据源中查找匹配项更新数组元素 * 如果属性值是对象,则尝试在数据源中查找匹配项更新该对象 * 自动处理单复数形式的数据源键名 */ function resolveDataReference(entity, data) { for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { // 修复:统一使用复数形式查找引用类型 let refType = attribute.replace(/\d/g, ''); // 尝试直接查找复数形式 if (!data[refType] && data[`${refType}s`]) { refType = `${refType}s`; } if (Array.isArray(entity[attribute])) { entity[attribute] = entity[attribute].map(item => data[refType]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { entity[attribute] = data[refType]?.find(updateItem => updateItem.id === entity[attribute].id) || entity[attribute]; } } } return entity; } /** * 懒加载处理器 * 负责管理实体类之间的关联依赖,实现按需加载 */ class LazyLoader { constructor(dataManager) { this.dataManager = dataManager; this.cache = new Map(); this.entityTypeMap = { bancai: 'bancais', dingdan: 'dingdans', mupi: 'mupis', chanpin: 'chanpins', kucun: 'kucuns', dingdan_bancai: 'dingdan_bancais', chanpin_zujian: 'chanpin_zujians', zujian: 'zujians', caizhi: 'caizhis', dingdan_chanpin: 'dingdan_chanpins', user: 'users', jinhuo: 'jinhuos' }; } /** * 创建实体代理 * @param {Object} entity 实体对象 * @param {string} entityType 实体类型 * @returns {Proxy} 返回代理后的实体 */ // 修复2:增强代理创建逻辑 createProxy(entity, entityType) { // 添加循环引用检测标记 if (entity.__isProxy) return entity; const handler = { get: (target, prop) => { console.log(prop) // 特殊属性处理 // if (prop === '__isProxy') return true; const value = target[prop]; // 基本类型直接返回 if (typeof value !== 'object' || value === null) { return value; } console.warn( baseProp) // 数组类型处理 if (Array.isArray(value)) { return value.map(item => item && !item.__isProxy ? this.createProxy(item, this.getEntityType(item)) : item ); } // 引用类型处理 const refType = this.getReferenceType(prop) || entityType; if (refType) { // 修复3:确保嵌套引用也被代理 if (!value.__isProxy) { return this.loadReference(value, refType); } } return value; }, set: (target, prop, value) => { // 清除相关缓存 this.cache.delete(this.getCacheKey(target)); target[prop] = value; return true; } }; const proxy = new Proxy(entity, handler); entity.__isProxy = true; // 标记为已代理 return proxy; } // 新增方法:根据实体类型获取缓存键 getCacheKey(entity) { if (!entity || !entity.id) return null; const entityType = this.getEntityType(entity) || 'unknown'; return `${entityType}_${entity.id}`; } // 新增方法:根据实体推断类型 getEntityType(entity) { if (!entity) return null; // 通过构造函数名或自定义属性判断类型 if (entity.constructor.name !== 'Object') { return entity.constructor.name.toLowerCase() + 's'; } return null; } // 修改:增强引用类型识别 getReferenceType(prop) { // 处理带数字后缀的属性 (mupi1 → mupis) const baseProp = prop.replace(/\d+$/, ''); const plural = this.entityTypeMap[baseProp] || `${baseProp}s`; // 检查类型是否存在 const ret=this.dataManager._rawData[plural] ? plural : null; console.warn( baseProp) if(!ret){ console.warn( baseProp) } return } // 修改:简化加载逻辑 async loadReference(ref, refType) { if (!ref || !ref.id) return ref; const cacheKey = `${refType}_${ref.id}`; if (this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } // 直接使用现有数据,移除同步调用 const entities = this.dataManager._rawData[refType] || []; const entity = entities.find(e => e.id === ref.id); if (entity) { // 修复5:不再使用resolveDataReference const proxy = this.createProxy(entity, refType); this.cache.set(cacheKey, proxy); return proxy; } return ref; // 保持原始引用 } /** * 加载多个关联引用 * @param {Array} refs 引用对象数组 * @param {string} refType 引用类型(复数形式) * @returns {Promise<Array>} 解析后的实体对象数组 */ async loadReferences(refs, refType) { if (!Array.isArray(refs)) return []; return Promise.all( refs.map(ref => this.loadReference(ref, refType)) ); } /** * 清除缓存 */ clearCache() { this.cache.clear(); } } class MiniProgramDataManager { constructor(baseUrl) { this.baseUrl = baseUrl; this.debug = true; // 调试模式开关 this.requestCount = 0; // 请求计数器 // 数据结构定义 this._rawData = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [], _lastModified: null, _lastSync: null }; // 初始化网络状态 this.networkAvailable = false; this.checkNetwork().then(type => { this.networkAvailable = type !== 'none'; }); this.lazyLoader = new LazyLoader(this); this.loadDataFromStorage(); this.isSyncing = false; this.lastSync = null; this.callbacks = { all: [], bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], chanpin_zujian: [], dingdan_bancai: [], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], jinhuo: [] }; this.syncQueue = Promise.resolve(); this.entiyeText = { bancai: '板材已存在', dingdan: '订单已存在', mupi: '木皮已存在', chanpin: '产品已存在', kucun: '已有库存记录', chanpin_zujian: '产品已有该组件', dingdan_bancai: '', zujian: '组件已定义过了', caizhi: '材质已定义过了', dingdan_chanpin: '订单下已有该产品', user: '' }; this.syncInterval = 5 * 60 * 1000; // 5分钟 this.storageKey = 'miniProgramData'; // 本地存储的键名 } get data() { const handler = { get: (target, prop) => { if (prop.startsWith('_')) return target[prop]; if (Array.isArray(target[prop])) { // 修复6:直接创建代理数组 return target[prop].map(item => this.lazyLoader.createProxy(item, prop.replace(/s$/, '')) ); } return target[prop]; }, set(target, prop, value) { // 修复7:设置时清除相关缓存 if (Array.isArray(value)) { value.forEach(item => this.lazyLoader.cache.delete( this.lazyLoader.getCacheKey(item)) ); } else { this.lazyLoader.cache.delete( this.lazyLoader.getCacheKey(value)); } target[prop] = value; return true; } }; return new Proxy(this._rawData, handler); } // 添加显式初始化方法 async initialize() { // 启动自动同步 this.startAutoSync(); // 执行首次数据同步 await this.syncData(); } /** * 启动自动同步定时器 * 每隔syncInterval毫秒检查并执行数据同步 * 如果已有同步任务进行中则跳过 */ startAutoSync() { if (this.autoSyncTimer) clearInterval(this.autoSyncTimer); this.autoSyncTimer = setInterval(() => { if (!this.isSyncing) this.syncData(); }, this.syncInterval); } /** * 停止自动同步 */ stopAutoSync() { clearInterval(this.autoSyncTimer); } /** * 检查网络状态 */ checkNetwork() { return new Promise((resolve) => { wx.getNetworkType({ success: (res) => { resolve(res.networkType); }, fail: () => { resolve('unknown'); } }); }); } /** * 获取所有数据(全量或增量) * @async * @param {string} [since] - 增量获取的时间戳,不传则全量获取 * @returns {Promise} 是否获取成功 * @description * 根据since参数决定全量或增量获取数据 * 增量获取时会合并新数据到现有数据 * 全量获取会直接替换现有数据 * 成功后会更新同步时间并保存到本地存储 * 失败时会触发错误回调,若无历史数据则抛出错误 */ async fetchAll(since) { try { console.log(since ? `增量获取数据(自${since})...` : '全量获取数据...'); const params = since ? { since } : {}; const result = await this.request('/app/all', 'GET', params); const resolvedData = result; // 更新networkData Object.keys(this._rawData).forEach(key => { if (key.startsWith('_')) return; if (resolvedData[key]) { if (since) { // 增量更新: 合并新数据到现有数据 resolvedData[key].forEach(newItem => { const index = this._rawData[key].findIndex(item => item.id === newItem.id); if (index >= 0) { this._rawData[key][index] = newItem; } else { this._rawData[key].push(newItem); } }); } else { // 全量更新: 直接替换 this._rawData[key] = resolvedData[key]; } } }); // 更新同步时间 this.lastSync = new Date(); this._rawData._lastSync = this.lastSync.toISOString(); // 保存到本地存储 this.saveDataToStorage(); this.triggerCallbacks('refresh', 'all', this.data); return true; } catch (error) { console.error('Fetch error:', error); this.triggerCallbacks('fetch_error', 'all', { error }); // 失败时尝试使用本地数据 if (!this.lastSync) { throw new Error('初始化数据获取失败'); } return false; } } /** * 微信小程序API请求封装 */ request(url, method = 'GET', data = null, retryCount = 3) { return new Promise((resolve, reject) => { const makeRequest = (attempt) => { const fullUrl = `${this.baseUrl}${url}`; if (this.debug) { console.log(`[请求] ${method} ${fullUrl}`, { attempt, data, timestamp: new Date().toISOString() }); } wx.request({ url: fullUrl, method, data, header: { 'Content-Type': 'application/json' }, success: (res) => { if (this.debug) { console.log(`[响应] ${fullUrl}`, { status: res.statusCode, data: res.data, headers: res.header }); } // 修复:更灵活的响应格式处理 if (!res.data) { const err = new Error('空响应数据'); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, err); } else { reject(err); } return; } // 修复:支持多种成功状态码响应格式 const isSuccess = res.statusCode >= 200 && res.statusCode < 300; const hasData = res.data && (res.data.data !== undefined || typeof res.data === 'object'); if (isSuccess && hasData) { resolve(res.data.data || res.data); } else { const errMsg = res.data.message || res.data.text || 'API错误'; const err = new Error(errMsg); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, err); } else { reject(err); } } }, fail: (err) => { if (this.debug) { console.error(`[失败] ${fullUrl}`, err); } const error = new Error(`网络请求失败: ${err.errMsg || '未知错误'}`); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, error); } else { reject(error); } } }); }; makeRequest(1); }); } retryRequest(makeRequest, attempt, retryCount, error) { const delay = 1000 * attempt; console.warn(`请求失败 (${attempt}/${retryCount}), ${delay}ms后重试:`, error.message); setTimeout(() => makeRequest(attempt + 1), delay); } /** * 注册回调函数 */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** * 注销回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** * 触发回调函数 */ triggerCallbacks(operation, entity, data) { this.callbacks.all.forEach(cb => cb(operation, entity, data)); if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } /** * 检查重复实体 */ checkDuplicate(entity, data) { // 修复:确保引用已解析 const resolvedData = resolveDataReference(data, this.data); switch (entity) { case 'bancai': return this.data.bancais.some(b => b.houdu === resolvedData.houdu && b.caizhi?.id === resolvedData.caizhi?.id && b.mupi1?.id === resolvedData.mupi1?.id && b.mupi2?.id === resolvedData.mupi2?.id ); case 'caizhi': return this.data.caizhis.some(c => c.name === resolvedData.name); case 'mupi': return this.data.mupis.some(m => m.name === resolvedData.name && m.you === resolvedData.you ); case 'chanpin': return this.data.chanpins.some(c => c.bianhao === resolvedData.bianhao); case 'zujian': return this.data.zujians.some(z => z.name === resolvedData.name); case 'dingdan': return this.data.dingdans.some(d => d.number === resolvedData.number); case 'chanpin_zujian': return this.data.chanpin_zujians.some(cz => cz.chanpin?.id === resolvedData.chanpin?.id && cz.zujian?.id === resolvedData.zujian?.id ); case 'dingdan_chanpin': return this.data.dingdan_chanpins.some(dc => dc.dingdan?.id === resolvedData.dingdan?.id && dc.chanpin?.id === resolvedData.chanpin?.id ); case 'dingdan_bancai': return this.data.dingdan_bancais.some(db => db.dingdan?.id === resolvedData.dingdan?.id && db.chanpin?.id === resolvedData.chanpin?.id && db.zujian?.id === resolvedData.zujian?.id && db.bancai?.id === resolvedData.bancai?.id ); case 'user': return this.data.users.some(u => u.name === resolvedData.name); default: return false; } } /** * CRUD操作通用方法 */ async crudOperation(operation, entity, data) { try { // 使用微信请求API替代fetch const result = await this.request(`/app/${operation}/${entity}`, 'POST', data); this.updateLocalData(operation, entity, result || data); this.triggerCallbacks(operation, entity, result || data); return result; } catch (error) { console.error('CRUD error:', error); this.triggerCallbacks(`${operation}_error`, entity, { data, error: error.message }); throw error; } } /** * 更新本地数据 * @param {string} operation - 操作类型: 'add' | 'update' | 'delete' * @param {string} entity - 实体名称 * @param {Object} newData - 新数据对象(包含id字段) * @description 根据操作类型对本地数据进行增删改操作 */ updateLocalData(operation, entity, newData) { const key = `${entity}s`; const entities = this._rawData[key]; // 确保新数据的引用已解析 const resolvedData = resolveDataReference(newData, this._rawData); switch (operation) { case 'add': entities.push(resolvedData); break; case 'update': const index = entities.findIndex(item => item.id === resolvedData.id); if (index !== -1) { // 修复:使用对象展开操作符确保属性完整覆盖 entities[index] = { ...entities[index], ...resolvedData }; } else { entities.push(resolvedData); } break; case 'delete': const deleteIndex = entities.findIndex(item => item.id === resolvedData.id); if (deleteIndex !== -1) { entities.splice(deleteIndex, 1); } break; } // 更新最后修改时间 this._rawData._lastModified = new Date().toISOString(); // 清除懒加载缓存 this.lazyLoader.clearCache(); // 保存修改后的数据到本地存储 this.saveDataToStorage(); } /** * 同步数据方法 * 该方法用于异步获取所有数据,并处理同步过程中的并发请求 * 如果同步正在进行中,会将请求标记为待处理(pendingSync) * 同步完成后会自动处理待处理的请求 * @async * @throws {Error} 当获取数据失败时会抛出错误并记录日志 */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { // 1. 先加载本地数据 this.loadDataFromStorage(); // 2. 获取最后同步时间,用于增量更新 const since = this._rawData._lastSync || null; // 3. 获取增量数据 await this.fetchAll(since); // 4. 清除懒加载缓存 this.lazyLoader.clearCache(); // 5. 保存更新后的数据到本地存储 this.saveDataToStorage(); // 6. 触发数据更新回调 this.triggerCallbacks('refresh', 'all', this.data); } catch (error) { console.error('Sync failed:', error); this.triggerCallbacks('sync_error', 'all', { error }); // 失败时尝试使用本地数据 if (!this._rawData._lastSync) { throw new Error('初始化数据同步失败'); } } finally { this.isSyncing = false; if (this.pendingSync) { this.pendingSync = false; this.syncData(); } } } /** * 从本地存储加载数据 * 使用微信小程序的同步存储API获取之前保存的数据 */ loadDataFromStorage() { try { const storedData = wx.getStorageSync(this.storageKey); if (storedData) { // 修复:加载到_rawData而非data代理对象 this._rawData = storedData; // 解析所有引用关系 // resolveDataReferences(this._rawData); } } catch (error) { console.error('加载本地存储数据失败:', error); // 提供默认空数据 this._rawData = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [], _lastModified: null, _lastSync: null }; } } /** * 保存数据到本地存储 * 使用微信小程序的同步存储API持久化当前数据 */ saveDataToStorage() { try { // 修复:保存_rawData而非localData wx.setStorageSync(this.storageKey, this._rawData); } catch (error) { console.error('保存数据到本地存储失败:', error); // 提示用户或执行降级策略 wx.showToast({ title: '数据保存失败,请稍后重试', icon: 'none' }); } } /** * 添加实体数据 * @async * @param {string} entity - 实体类型 * @param {Object} data - 要添加的实体数据 * @returns {Promise} 返回CRUD操作结果 * @throws {Error} 如果数据已存在则抛出错误 */ async addEntity(entity, data) { if (this.checkDuplicate(entity, data)) { const errorMsg = `${this.entiyeText[entity]}`; this.triggerCallbacks('duplicate_error', entity, { data, error: errorMsg }); throw new Error(errorMsg); } return this.crudOperation('add', entity, data); } /** * 更新实体 */ async updateEntity(entity, data) { return this.crudOperation('update', entity, data); } /** * 删除实体 */ async deleteEntity(entity, id) { return this.crudOperation('delete', entity, { id }); } getBancaisForZujian(zujianId) { const dingdan_bancais = this.data.dingdan_bancais.filter(db => db.zujian?.id == zujianId); return dingdan_bancais.map(db => db.bancai).filter(Boolean); } /** * 获取板材的库存信息 */ getKucunForBancai(bancaiId) { return this.data.kucuns.find(k => k.bancai?.id == bancaiId); } } // 导出模块 module.exports = MiniProgramDataManager;---------------------------------------------第116行的 const handler = {}中的函数就没触发过----------------------------------[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details. [system] WeChatLib: 3.8.10 (2025.7.4 16:39:26) [system] Subpackages: N/A [system] LazyCodeLoading: false app.js? [sm]:11 小程序启动 app.js? [sm]:18 检测到已登录状态,直接登录 MiniProgramDataManager.js? [sm]:375 增量获取数据(自2025-07-22T08:02:47.308Z)... MiniProgramDataManager.js? [sm]:433 [请求] GET http://192.168.1.11:8080/app/all {attempt: 1, data: {…}, timestamp: "2025-07-22T08:05:08.107Z"} Tue Jul 22 2025 16:05:08 GMT+0800 (中国标准时间) 配置中关闭合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书检查 工具未校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书。 makeRequest @ MiniProgramDataManager.js? [sm]:440 (anonymous) @ MiniProgramDataManager.js? [sm]:497 request @ MiniProgramDataManager.js? [sm]:428 _callee4$ @ MiniProgramDataManager.js? [sm]:378 s @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 asyncGeneratorStep @ asyncToGenerator.js?forceSync=true:1 c @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 fetchAll @ MiniProgramDataManager.js? [sm]:422 _callee6$ @ MiniProgramDataManager.js? [sm]:679 s @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 asyncGeneratorStep @ asyncToGenerator.js?forceSync=true:1 c @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 syncData @ MiniProgramDataManager.js? [sm]:705 _callee3$ @ MiniProgramDataManager.js? [sm]:323 s @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 asyncGeneratorStep @ asyncToGenerator.js?forceSync=true:1 c @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 initialize @ MiniProgramDataManager.js? [sm]:324 onLaunch @ app.js? [sm]:26 (anonymous) @ app.js? [sm]:2 Show 2 more frames MiniProgramDataManager.js? [sm]:449 [响应] http://192.168.1.11:8080/app/all {status: 200, data: {…}, headers: Proxy} index.js? [sm]:44 index页面加载 index.js? [sm]:108 开始更新表格数据 - 优化版 index.js? [sm]:114 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 3, kucun: null, …} updateTable @ index.js? [sm]:114 updatePageData @ index.js? [sm]:81 onLoad @ index.js? [sm]:56 index.js? [sm]:61 首页显示 [system] Launch Time: 3481 ms
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值