const cache = require('./data-cache'); // 页面各自记录版本,三级页面修改不会被某一个上层页面“消费”掉。 function withDataCache(definition, loaders) { const actions = Array.from(new Set([].concat(...Object.keys(loaders).map(name => loaders[name])))); Object.keys(loaders).forEach(name => { const load = definition[name]; if (!load) return; definition[name] = function(...args) { if (!this._dataLoads) this._dataLoads = {}; const dependencies = loaders[name]; const signature = cache.signature(dependencies); const previous = this._dataLoads[name]; const key = JSON.stringify(args); if (previous && previous.pending && (previous.signature !== signature || previous.key !== key)) { return previous.pending.then(() => this[name](...args)); } const ttl = Math.min(...dependencies.map(action => cache.policies[action] || cache.TTL)); if (previous && previous.signature === signature && previous.key === key) { if (previous.pending) return previous.pending; if (Date.now() - previous.time < ttl && !this.data.loadError && !this.data.homeError && !this.data.statsError && !this.data.bindingError && !this.data.commentsError) return Promise.resolve(); } const record = { signature, key, time: 0 }; this._dataLoads[name] = record; record.pending = Promise.resolve().then(() => load.apply(this, args)).then(result => { if (!this.data.loadError && !this.data.homeError && !this.data.statsError && !this.data.bindingError && !this.data.commentsError) { record.time = Date.now(); if (name !== 'loadComments') this._hasCachedData = true; } record.pending = null; return result; }, error => { record.pending = null; throw error; }); return record.pending; }; }); ['onPullDownRefresh', 'onRefresh'].forEach(name => { const refresh = definition[name]; if (refresh) definition[name] = function(...args) { cache.invalidate(actions); return refresh.apply(this, args); }; }); return definition; } module.exports = { withDataCache };