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

Blazor WebAssembly应用中何时更新IndexedDB数据?

问题场景与疑问

我有一个Blazor WebAssembly(PWA)项目,搭配独立的ASP.NET API获取数据库中的产品数据。调用/api/products/getAllProducts接口因产品数量较多需耗时数秒,服务器端产品数据每日通过服务更新一次。

为支持客户端离线使用,我正实现IndexedDB用于本地产品存储,目前相关未测试代码位于产品页面的代码块中:

private IEnumerable<Product>? products;

protected override async Task OnInitializedAsync()
{
    // get products from the api
    products = await Http.GetFromJsonAsync<Product[]>("/api/products/GetAllProducts");


    // add products fetched from api into local storage
    using var db = await DbFactory.Create<IndexDb>();
    db.allProducts.Clear();
    foreach ( var product in products)
    {
        db.allProducts.Add(product);
    }
    await db.SaveChanges();


    // get products from local storage
    products = db.allProducts;
}

我的疑问是:在不拖慢或中断应用的前提下,应何时从API刷新/重新填充本地IndexedDB产品列表?应用启动时是否可行?还是在用户打开产品列表页面时?实际上我只需用户每日首次打开时更新一次即可。

解决方案
  • 优先加载本地数据,保证页面响应速度:页面初始化时先从IndexedDB读取产品数据直接渲染,避免用户等待API请求完成,解决当前代码阻塞UI的问题。
  • 后台异步执行更新检查:推荐在应用首次启动时(比如根组件的OnInitializedAsync或Program.cs的初始化逻辑)触发更新逻辑,放在后台异步执行不影响UI渲染。这样不管用户进入哪个页面,都能保证本地数据是当日最新的;如果只想在用户访问产品页面时检查,也可以把逻辑放在产品页面的初始化后台任务中。
  • 记录最后更新时间,实现每日更新一次:在IndexedDB中存储一个「最后同步时间」字段,每次触发更新前先读取这个时间,判断距离当前是否超过24小时,只有符合条件才发起API请求更新本地数据。
  • 更新完成后通知UI刷新(可选):如果更新过程中用户已经在产品页面,更新完成后可以触发状态变更,让用户看到最新数据。

优化后的代码示例

private IEnumerable<Product>? products;
private bool isUpdating = false;

protected override async Task OnInitializedAsync()
{
    // 第一步:优先从本地IndexedDB加载数据,快速渲染页面
    using var db = await DbFactory.Create<IndexDb>();
    products = db.allProducts.ToList();
    StateHasChanged(); // 立即触发渲染

    // 第二步:后台异步检查是否需要更新
    await CheckAndUpdateProductsAsync();
}

private async Task CheckAndUpdateProductsAsync()
{
    if (isUpdating) return;
    isUpdating = true;

    try
    {
        using var db = await DbFactory.Create<IndexDb>();
        // 读取最后同步时间(需在IndexDb中添加对应存储实体)
        var lastSync = db.lastSyncRecords.FirstOrDefault()?.LastSyncTime ?? DateTime.MinValue;
        
        // 判断是否超过24小时需要更新
        if (DateTime.Now - lastSync > TimeSpan.FromHours(24))
        {
            // 后台请求API获取最新数据
            var latestProducts = await Http.GetFromJsonAsync<Product[]>("/api/products/GetAllProducts");
            if (latestProducts != null)
            {
                // 更新本地产品存储
                db.allProducts.Clear();
                db.allProducts.AddRange(latestProducts);
                
                // 更新同步时间记录
                db.lastSyncRecords.Clear();
                db.lastSyncRecords.Add(new SyncRecord { LastSyncTime = DateTime.Now });
                
                await db.SaveChanges();

                // 更新页面数据并通知渲染
                products = latestProducts;
                StateHasChanged();
            }
        }
    }
    catch (Exception ex)
    {
        // 处理网络异常(比如离线时忽略,不影响应用使用)
        Console.WriteLine("产品数据更新失败:" + ex.Message);
    }
    finally
    {
        isUpdating = false;
    }
}

关键细节说明

  • 把API请求和本地存储更新放到后台异步任务中,页面先展示缓存数据,用户无感知等待
  • 通过「最后同步时间」控制每日仅更新一次,避免无效重复请求
  • 异常处理确保网络问题(比如离线)不会导致应用崩溃
  • 可以将同步时间检查逻辑抽成全局服务,在应用启动时统一执行,覆盖所有页面场景

内容的提问来源于stack exchange,提问作者Jeremias Röner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:47:23