Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 026bc99

Browse files
committed
Performance improvements for fetchall
1 parent 2c9a514 commit 026bc99

1 file changed

Lines changed: 42 additions & 27 deletions

File tree

src/utils/ui/mixins/ProviderFetchMixin.ts

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import { Component } from 'vue-facing-decorator'
12
import { GenericProvider } from '../providers/generics/genericProvider'
23
import ProviderMixin from './ProviderMixin'
3-
import { vxm } from '@/mainWindow/store'
4-
import { Component } from 'vue-facing-decorator'
54
import { convertProxy } from '../common'
5+
import { vxm } from '@/mainWindow/store'
66

77
@Component
88
export default class ProviderFetchMixin extends ProviderMixin {
99
private loadingMap: Record<string, boolean> = {}
1010
public songList: Song[] = []
11+
12+
private songMap: Record<string, Song> = {}
1113
generator:
1214
| ((
1315
provider: GenericProvider,
@@ -45,21 +47,12 @@ export default class ProviderFetchMixin extends ProviderMixin {
4547
return Object.values(this.loadingMap).includes(true)
4648
}
4749

48-
private async fetchProviderSonglist(provider: GenericProvider) {
50+
private async *fetchProviderSonglist(provider: GenericProvider) {
4951
this.loadingMap[provider.key] = true
5052
if (this.generator) {
5153
for await (const items of this.generator(provider, this.nextPageToken[provider.key])) {
5254
this.nextPageToken[provider.key] = items.nextPageToken
53-
for (const s of items.songs) {
54-
if (!this.songList.find((val) => val._id === s._id)) {
55-
this.songList.push(s)
56-
57-
if (!this.optionalSongList[provider.key]) {
58-
this.optionalSongList[provider.key] = []
59-
}
60-
this.optionalSongList[provider.key].push(s._id)
61-
}
62-
}
55+
yield items
6356
}
6457
}
6558

@@ -70,62 +63,84 @@ export default class ProviderFetchMixin extends ProviderMixin {
7063

7164
async fetchSongList() {
7265
this.loadingMap['local'] = true
73-
this.songList = (await this.localSongFetch?.(convertProxy(vxm.themes.songSortBy))) ?? []
66+
;((await this.localSongFetch?.(convertProxy(vxm.themes.songSortBy))) ?? []).forEach((val) => {
67+
this.songMap[val._id] = val
68+
})
7469
this.optionalSongList['local'] = this.songList.map((val) => val._id)
7570
this.loadingMap['local'] = false
7671
}
7772

7873
public async fetchAll(afterFetch?: (songs: Song[]) => void, onFetchEnded?: (songCount: number) => void) {
7974
if (!this.isFetching) {
8075
this.isFetching = true
81-
let songListLastSong = this.songList.length - 1
8276

8377
let count = 0
84-
8578
for (const key of Object.keys(this.nextPageToken)) {
8679
while (this.nextPageToken[key]) {
87-
await this.loadNextPage()
88-
const newList = this.songList.slice(songListLastSong)
89-
count += newList.length
90-
afterFetch?.(newList)
91-
songListLastSong = this.songList.length
80+
for await (const songs of this.loadNextPageWrapper()) {
81+
afterFetch?.(songs.songs)
82+
count += songs.songs.length
83+
}
9284
}
9385
}
9486

87+
this.songList = Object.values(this.songMap)
9588
onFetchEnded?.(count)
9689
this.isFetching = false
9790
}
9891
}
9992

10093
async loadNextPage() {
94+
for await (const s of this.loadNextPageWrapper()) {
95+
}
96+
this.songList = Object.values(this.songMap)
97+
}
98+
99+
async *loadNextPageWrapper() {
101100
for (const key of Object.keys(this.nextPageToken)) {
102101
if (this.nextPageToken[key]) {
103102
for (const [key, checked] of Object.entries(this.activeProviders)) {
104103
if (checked) {
105-
await this.fetchRemoteProviderByKey(key)
104+
for await (const s of this.fetchRemoteProviderByKey(key)) {
105+
yield s
106+
}
106107
}
107108
}
108109
}
109110
}
110111
}
111112

112-
private async fetchRemoteProviderByKey(key: string) {
113+
private async *fetchRemoteProviderByKey(key: string) {
113114
const provider = this.getProviderByKey(key)
114115
if (provider) {
115-
await this.fetchProviderSonglist(provider)
116+
for await (const items of this.fetchProviderSonglist(provider)) {
117+
for (const s of items.songs) {
118+
if (!this.songMap[s._id]) {
119+
this.songMap[s._id] = s
120+
if (!this.optionalSongList[provider.key]) {
121+
this.optionalSongList[provider.key] = []
122+
}
123+
this.optionalSongList[provider.key].push(s._id)
124+
}
125+
}
126+
127+
yield items
128+
}
116129
return
117130
}
118131
}
119132

120-
onProviderChanged({ key, checked }: { key: string; checked: boolean }) {
133+
async onProviderChanged({ key, checked }: { key: string; checked: boolean }) {
121134
this.activeProviders[key] = checked
122135
if (checked) {
123-
this.fetchRemoteProviderByKey(key)
136+
for await (const s of this.fetchRemoteProviderByKey(key)) {
137+
}
138+
this.songList = Object.values(this.songMap)
124139
}
125140
}
126141

127142
clearSongList() {
128-
this.songList = []
143+
this.songMap = {}
129144
}
130145

131146
clearNextPageTokens() {

0 commit comments

Comments
 (0)