From f545118fc77f7f972319953a2a4dd2b46ebebc29 Mon Sep 17 00:00:00 2001 From: Bing Sun Date: Tue, 12 May 2020 23:26:10 +0800 Subject: [PATCH] make_model: prelinary loading state support --- src/util/make_model.js | 51 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/util/make_model.js b/src/util/make_model.js index fd122b0..d6b6ffe 100644 --- a/src/util/make_model.js +++ b/src/util/make_model.js @@ -51,7 +51,9 @@ export default (options={}) => { // async states xhr: null, promise: null, - loading: false + loading: false, + loading_offset: null, + loading_limit: null } // construct the model @@ -63,6 +65,9 @@ export default (options={}) => { ambient_changed() { return _state.ambient != _state.last_ambient }, + loading() { + return _state.loading + }, // clean state and cache if necessary clean() { @@ -70,6 +75,8 @@ export default (options={}) => { _state.xhr = null _state.promise = null _state.loading = false + _state.loading_offset = null + _state.loading_limit = null // update ambient state _state.last_ambient = _state.ambient @@ -97,23 +104,21 @@ export default (options={}) => { if (this.data(offset, limit).length > 0 && !this.data(offset, limit).includes(undefined)) return Promise.resolve(this.data(offset, limit)) - // be lazy 2: if there is a promise, return it if ambient matches or - // cancel it - if (_state.promise != null) { - if (this.ambient_changed()) { + // be lazy 2: if the model is loading the same slice of data with the + // same ambient, return the current promise; otherwise cancel it + if (this.loading()) { + if (!this.ambient_changed() && _state.loading_offset == offset && _state.loading_limit == limit) + return _state.promise + else { if (_state.xhr != null) _state.xhr.abort() _state.xhr = null } - else - return _state.promise } - // TODO - // ambient = select + order + limit/offset - // if ambient is changed, cancel currently loading xhr; otherwise return - // current promise + // update state + _state.loading = true - // now the hard work + // construct the promise _state.promise = _configs.api.request({ method: 'GET', url: _configs.endpoint, @@ -189,11 +194,21 @@ export default (options={}) => { if (this.data().length == _cache.count && !this.data().includes(undefined)) return Promise.resolve(this.data()) - // be lazy 2: if there is a promise, return it if ambient matches or - // cancel it - if (_state.promise != null) - return _state.promise + // be lazy 2: if the model is loading the same slice of data with the + // same ambient, return the current promise; otherwise cancel it + if (this.loading()) { + if (!this.ambient_changed() && _state.loading_offset == offset && _state.loading_limit == limit) + return _state.promise + else { + if (_state.xhr != null) _state.xhr.abort() + _state.xhr = null + } + } + + // update state + _state.loading = true + // construct the promise _state.promise = _configs.api.request({ method: 'POST', url: '/rpc/select_all', @@ -213,10 +228,6 @@ export default (options={}) => { return data }) - - // clean state - _state.promise = null - this.reset() }).finally(() => { this.clean() })