提交
This commit is contained in:
@@ -12,6 +12,7 @@ import type {
|
||||
PreviewResponse,
|
||||
ScreenerQueryItem,
|
||||
ScreenerRunRequest,
|
||||
ScreenerStreamEvent,
|
||||
ScreenerRunResponse,
|
||||
ScreenerSyncRequest,
|
||||
ScreenerSyncStatus,
|
||||
@@ -120,10 +121,38 @@ export async function postEventBacktest(req: EventBacktestRequest): Promise<Even
|
||||
}
|
||||
}
|
||||
|
||||
export async function runScreener(req: ScreenerRunRequest): Promise<ScreenerRunResponse> {
|
||||
const res = await apiFetch('/api/screener/run', { method: 'POST', body: JSON.stringify(req) });
|
||||
/** 选股流式执行:逐行回调 NDJSON 事件(阶段/进度/解析条件),最终返回完整结果。
|
||||
* signal 中止后(含读流中途)以 AbortError 拒绝,由调用方决定如何呈现。 */
|
||||
export async function runScreener(
|
||||
req: ScreenerRunRequest,
|
||||
onEvent?: (ev: ScreenerStreamEvent) => void,
|
||||
signal?: AbortSignal,
|
||||
): Promise<ScreenerRunResponse> {
|
||||
const res = await apiFetch('/api/screener/run', { method: 'POST', body: JSON.stringify(req), signal });
|
||||
if (!res.ok) throw new ApiError(await readError(res, `选股失败 (HTTP ${res.status})`), res.status);
|
||||
return (await res.json()) as ScreenerRunResponse;
|
||||
if (!res.body) throw new ApiError('当前环境不支持流式响应', 0);
|
||||
|
||||
const reader = res.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buf = '';
|
||||
let result: ScreenerRunResponse | null = null;
|
||||
for (;;) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
buf += decoder.decode(value, { stream: true });
|
||||
let nl: number;
|
||||
while ((nl = buf.indexOf('\n')) >= 0) {
|
||||
const line = buf.slice(0, nl).trim();
|
||||
buf = buf.slice(nl + 1);
|
||||
if (!line) continue;
|
||||
const ev = JSON.parse(line) as ScreenerStreamEvent;
|
||||
if (ev.type === 'error') throw new ApiError(ev.message, ev.code ?? 0);
|
||||
if (ev.type === 'result') result = ev.result;
|
||||
onEvent?.(ev);
|
||||
}
|
||||
}
|
||||
if (!result) throw new ApiError('选股响应中断(未收到结果事件)', 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function startScreenerSync(req: ScreenerSyncRequest = {}): Promise<ScreenerSyncStatus> {
|
||||
|
||||
Reference in New Issue
Block a user