A few months ago I wrote this module but, coming back to it, I find it a bit hard to read and reason about. I want to ask community's opinion on whether this needs to be refactored, and how I could approach this.
(function (q) {
'use strict';
var DELAY_BEFORE_RENDERING_NEXT_PAGE_VIEW = 3 * 1000;
window.st.viewer.Helper.PageViewFactory = (function () {
function promiseRenderView(page, token) {
return page.fetchUnlessReady()
.then(token.throwIfCanceled)
.then(function () {
var view = new window.st.viewer.View.PageView({
model: page
});
view.render();
return view;
});
}
var scheduledPage,
scheduledPromise;
function scheduleRenderNextView(page, token) {
// After some time passes, prefetch and prerender next page view
// so if it is requested (very likely), we can re-use an existing promise.
scheduledPage = null;
scheduledPromise = null;
q.delay(DELAY_BEFORE_RENDERING_NEXT_PAGE_VIEW)
.then(token.throwIfCanceled)
.then(function () {
return page.promiseNext();
})
.then(token.throwIfCanceled)
.then(function (nextPage) {
if (nextPage) {
scheduledPage = nextPage;
scheduledPromise = promiseRenderView(nextPage, window.st.Helper.CancellationToken.getNone());
} else {
scheduledPage = null;
scheduledPromise = null;
}
})
.catch(token.catchItself)
.done();
}
function scheduleRenderView(page, token) {
var promise = (page !== scheduledPage) ?
promiseRenderView(page, token) :
scheduledPromise;
scheduleRenderNextView(page, token);
return promise;
}
return {
scheduleRenderView: scheduleRenderView
};
})();
})(Q);
This module exports a single function called scheduleRenderView
. Its purpose is, given a page
model and a cancellation token, do the following steps asynchronously:
- Fully fetch
page
model (it may be loaded partially); - Create and render (in memory) a
PageView
for it; - Return this view to the caller;
Additionally, after a 3 second delay:
- Request next
page
by callingpromiseNext
; - Pre-render next page by repeating steps 1-3 for it and store the pre-rendered view in case it gets requested the next time
scheduleRenderView
is called (very likely)
- Request next
The user views pages one by one, and I wanted to anticipate the most likely scenario where she will request the next page.
I also wanted to make this optimization invisible to the calling code.
Is this code hard to comprehend? Are the simpler ways to achieve the same?