diff --git a/webui/src/api/search.ts b/webui/src/api/search.ts index 41e7866b..9837c222 100644 --- a/webui/src/api/search.ts +++ b/webui/src/api/search.ts @@ -7,50 +7,7 @@ import type { BangumiRule } from '#/bangumi'; export const apiSearch = { /** * 番剧搜索接口是 Server Send 流式数据,每条是一个 Bangumi JSON 字符串, - * 使用接口方式需要订阅使用 - * - * Usage Example: - * - * ```ts - * import { - * Subject, - * tap, - * map, - * switchMap, - * debounceTime, - * } from 'rxjs'; - * - * - * const input$ = new Subject(); - * const onInput = (e: Event) => input$.next(e.target); - * - * // vue: - * - * const bangumiInfo$ = apiSearch.get('魔女之旅'); - * - * // vue: start loading animation - * - * input$.pipe( - * debounceTime(1000), - * tap((input: string) => { - * console.log('input', input) - * // clear Search Result List - * }), - * - * // switchMap 把输入 keyword 查询为 bangumiInfo$ 流,多次输入停用前一次查询 - * switchMap((input: string) => apiSearch(input, site)), - * - * tap((bangumi: BangumiRule) => console.log(bangumi)), - * tap((bangumi: BangumiRule) => { - * console.log('bangumi', bangumi) - * // set bangumi info to Search Result List - * }), - * ).subscribe({ - * complete() { - * // end of stream, stop loading animation - * }, - * }) - * ``` + * 使用接口方式是监听连接消息后,转为 Observable 配合外层调用时 switchMap 订阅使用 */ get(keyword: string, site = 'mikan'): Observable { const bangumiInfo$ = new Observable(observer => { @@ -64,11 +21,13 @@ export const apiSearch = { const data: BangumiRule = JSON.parse(ev.data); observer.next(data); } catch (error) { - observer.error(error); + console.error('[/search/bangumi] Parse Error |', { keyword }, 'response:', ev.data) } }; - eventSource.onerror = ev => observer.error(ev); + eventSource.onerror = ev => { + console.error('[/search/bangumi] Server Error |', { keyword }, 'error:', ev) + }; return () => { eventSource.close(); diff --git a/webui/src/components/basic/ab-search.vue b/webui/src/components/basic/ab-search.vue index bf5dd858..9b4a073a 100644 --- a/webui/src/components/basic/ab-search.vue +++ b/webui/src/components/basic/ab-search.vue @@ -3,7 +3,6 @@ import {Down, Search} from '@icon-park/vue-next'; const { onSelect, - onInput, onSearch, inputValue, selectingProvider, @@ -43,12 +42,11 @@ onMounted(() => { />
(); + watch(inputValue, input => { + input$.next(input); + }) + const {execute: getProviders, onResult: onGetProvidersResult} = useApi( apiSearch.getProvider ); @@ -33,27 +37,21 @@ export function useSearchStore() { * - 切换 provider 源站时触发搜索 */ - - const bangumiInfo$ = input$.pipe( debounceTime(600), tap(() => { + // 有输入更新后清理之前的搜索结果 bangumiList.value = []; }), filter(Boolean), - switchMap((input: string) => apiSearch.get(input, provider.value).pipe(takeUntil(input$))), + // switchMap 把输入 keyword 查询为 bangumiInfo$ 流,多次输入自动取消并停止前一次查询 + switchMap((input: string) => apiSearch.get(input, provider.value)), tap((bangumi: BangumiRule) => { bangumiList.value.push(bangumi); }), ) .subscribe() - function onInput(e: Event) { - const value = (e.target as HTMLInputElement).value; - input$.next(value); - inputValue.value = value; - } - function onSearch() { input$.next(inputValue.value); } @@ -70,7 +68,6 @@ export function useSearchStore() { inputValue, selectingProvider, onSelect, - onInput, onSearch, provider, getProviders,