From ef4e0b1a15d58814518117d096c5d9e4b0102cba Mon Sep 17 00:00:00 2001 From: Bing Sun Date: Tue, 12 May 2020 22:22:57 +0800 Subject: [PATCH] make_model: polish the state & cache handling --- src/util/make_model.js | 57 +++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/util/make_model.js b/src/util/make_model.js index eb20761..fd122b0 100644 --- a/src/util/make_model.js +++ b/src/util/make_model.js @@ -37,18 +37,18 @@ export default (options={}) => { // private model cache & meta-info let _cache = { - // upstream (data) cache + // upstream data cache data: null, count: null, - upstream_limit: null, - - // local cache - ambient: null, - last_ambient: null, + upstream_limit: null } - // some random variables to make things work + // model state let _state = { + // model ambient that determines the data content + ambient: null, + last_ambient: null, + // async states xhr: null, promise: null, loading: false @@ -61,24 +61,29 @@ export default (options={}) => { cache() { return _cache }, data(offset=0, limit=Infinity) { return _cache.data && _cache.data.slice(offset, offset+limit) || [] }, ambient_changed() { - return _cache.ambient != _cache.last_ambient + return _state.ambient != _state.last_ambient }, - reset() { - let ambient_queries = [ + + // clean state and cache if necessary + clean() { + // always clean async state + _state.xhr = null + _state.promise = null + _state.loading = false + + // update ambient state + _state.last_ambient = _state.ambient + _state.ambient =JSON.stringify([ ...(_configs.selects ? _configs.selects : []), ...(_configs.wheres ? _configs.wheres.map(where => ({label: where.label, op: where.op, value: typeof where.value == 'function' ? where.value() : where.value})) : []), ...(_configs.order ? _configs.order : []) - ] - - _cache.last_ambient = _cache.ambient - _cache.ambient =JSON.stringify(ambient_queries) + ]) + // clean cache if ambient changes if (this.ambient_changed()) { _cache.data = [] _cache.count = null _cache.upstream_limit = null - _state.xhr = null - //this.fully_loaded = false } }, @@ -94,8 +99,14 @@ export default (options={}) => { // be lazy 2: if there is a promise, return it if ambient matches or // cancel it - if (_state.promise != null) - return _state.promise + if (_state.promise != null) { + if (this.ambient_changed()) { + if (_state.xhr != null) _state.xhr.abort() + _state.xhr = null + } + else + return _state.promise + } // TODO // ambient = select + order + limit/offset @@ -164,12 +175,10 @@ export default (options={}) => { if (_end - _begin + 1 < limit) console.warn('The response range is narrower than requested, probably due to an upstream hard limit.') - // clean model state - _state.promise = null - this.reset() - // return data return _cache.data.slice(_begin, _end + 1) + }).finally(() => { + this.clean() }) return _state.promise @@ -208,6 +217,8 @@ export default (options={}) => { // clean state _state.promise = null this.reset() + }).finally(() => { + this.clean() }) return _state.promise @@ -271,6 +282,6 @@ export default (options={}) => { } // initialize model - _model.reset() + _model.clean() return _model }