From 6d8f4e22efed5feeb7a261946ad088e3e3f2cc3c Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Wed, 29 Aug 2018 22:03:29 -0700 Subject: [PATCH] fix worker ordering (#522) --- routes/_actions/createMakeProps.js | 47 +++++++++++++++++++++++ routes/_components/timeline/Timeline.html | 17 ++------ 2 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 routes/_actions/createMakeProps.js diff --git a/routes/_actions/createMakeProps.js b/routes/_actions/createMakeProps.js new file mode 100644 index 0000000..2f483d5 --- /dev/null +++ b/routes/_actions/createMakeProps.js @@ -0,0 +1,47 @@ +import { database } from '../_database/database' + +async function getNotification (instanceName, timelineType, timelineValue, itemId) { + return { + timelineType, + timelineValue, + notification: await database.getNotification(instanceName, itemId) + } +} + +async function getStatus (instanceName, timelineType, timelineValue, itemId) { + return { + timelineType, + timelineValue, + status: await database.getStatus(instanceName, itemId) + } +} + +export function createMakeProps (instanceName, timelineType, timelineValue) { + let taskCount = 0 + let pending = [] + + // The worker-powered indexeddb promises can resolve in arbitrary order, + // causing the timeline to load in a jerky way. With this function, we + // wait for all promises to resolve before resolving them all in one go. + function awaitAllTasksComplete () { + return new Promise(resolve => { + taskCount-- + pending.push(resolve) + if (taskCount === 0) { + pending.forEach(_ => _()) + pending = [] + } + }) + } + + return (itemId) => { + taskCount++ + let promise = timelineType === 'notifications' + ? getNotification(instanceName, timelineType, timelineValue, itemId) + : getStatus(instanceName, timelineType, timelineValue, itemId) + + return promise.then(res => { + return awaitAllTasksComplete().then(() => res) + }) + } +} diff --git a/routes/_components/timeline/Timeline.html b/routes/_components/timeline/Timeline.html index afc21eb..2169a60 100644 --- a/routes/_components/timeline/Timeline.html +++ b/routes/_components/timeline/Timeline.html @@ -41,7 +41,6 @@ importNotificationVirtualListItem } from '../../_utils/asyncModules' import { timelines } from '../../_static/timelines' - import { database } from '../../_database/database' import { fetchTimelineItemsOnScrollToBottom, setupTimeline, @@ -55,6 +54,7 @@ import isEqual from 'lodash-es/isEqual' import { doubleRAF } from '../../_utils/doubleRAF' import { observe } from 'svelte-extras' + import { createMakeProps } from '../../_actions/createMakeProps' export default { oncreate () { @@ -92,18 +92,9 @@ listItemComponent: results[1] })) }, - makeProps: ({ $currentInstance, timelineType, timelineValue }) => async (itemId) => { - let res = { - timelineType, - timelineValue - } - if (timelineType === 'notifications') { - res.notification = await database.getNotification($currentInstance, itemId) - } else { - res.status = await database.getStatus($currentInstance, itemId) - } - return res - }, + makeProps: ({ $currentInstance, timelineType, timelineValue }) => ( + createMakeProps($currentInstance, timelineType, timelineValue) + ), label: ({ timeline, $currentInstance, timelineType, timelineValue }) => { if (timelines[timeline]) { return `Statuses: ${timelines[timeline].label} timeline on ${$currentInstance}`