You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Akita中selectAll在服务调用完成前返回空列表问题咨询

为什么会先返回空列表

Akita的EntityStore初始化时,实体集合的默认初始值就是空数组。所有通过selectXXX方法创建的Observable,被订阅时会优先推送当前store的最新状态值,此时你的异步服务请求还未完成、store还未写入数据,所以第一次推送的就是初始空数组。等到服务请求返回、调用WidgetStore.add更新store后,才会推送第二次包含真实数据的结果。

如何过滤初始化的空数组

你可以通过给store新增自定义加载状态标记实现需求,步骤如下:

  1. 扩展WidgetState,新增字段标记历史数据是否完成加载
// widget.state.ts
import { EntityState } from '@datorama/akita';

export interface WidgetState extends EntityState<WidgetTO, number> {
  isHistorikkLoaded: boolean;
}
  1. 初始化WidgetStore时给状态字段设默认值false
// widget.store.ts
@Injectable({ providedIn: 'root' })
export class WidgetStore extends EntityStore<WidgetState> {
  constructor() {
    super({
      isHistorikkLoaded: false
    });
  }
}
  1. 数据请求成功后,同步更新加载状态为true
private fetchWidgetHistorikk() {
  this.WidgetService.getWidgetHistorikk().pipe(filter(h => !!h)).subscribe(liste => {
    this.WidgetStore.add(liste);
    // 标记数据加载流程完成
    this.WidgetStore.update({ isHistorikkLoaded: true });
  });
}
  1. 修改Query中的查询流,组合加载状态过滤未初始化的空值
@Injectable({ providedIn: 'root' })
export class WidgetQuery extends QueryEntity<WidgetState, WidgetTO> {
  public Widget$: Observable<WidgetTO> = this.selectActive().pipe(filter(k => !!k));
  public WidgetHistorikk$: Observable<WidgetTO[]> = combineLatest([
    this.selectAll({sortBy: 'WidgetId', sortByOrder: Order.DESC}),
    this.select(state => state.isHistorikkLoaded)
  ]).pipe(
    // 仅在加载完成后向下游推送数据,空数组也会正常推送
    filter(([_, isLoaded]) => isLoaded),
    map(([historikkList]) => historikkList)
  );

  constructor(protected store: WidgetStore) {
    super(store);
  }
}

注:不推荐使用skip(1)实现该需求,若异步请求速度快于订阅时机,会误跳过真实有效数据。

内容的提问来源于stack exchange,提问作者vikingsteve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:57:03