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

为何第二次调用LocalStorage GetAsync方法无法获取值?

问题

我基于JS文件实现了LocalStorage服务,用GetAsync方法获取存储的授权Token对象(包含UserID、UserName、UserSurname三个字段)。

相关代码如下:

localStorage.js

function get(key) {
    console.log('getItem')
    return localStorage.getItem(key)
}

ILocalStorageService.cs

public async Task<T> GetAsync<T>(string key) where T : class
{
    var data = await jsRuntime.InvokeAsync<string>("get", key);
    Console.Write("getItem");
    if (string.IsNullOrEmpty(data)) 
    { Console.WriteLine("LocalStorageService: token is null"); return null; }
    return JsonSerializer.Deserialize<T>(data);
}

Token.cs

public class Token
{
    public string UserID { get; set; }
    public string UserName { get; set; }
    public string UserSurname { get; set; }
}

我两次调用该方法:第一次在页面加载的授权逻辑中可正常获取Token;第二次调用时,Chrome控制台显示两次getItem,但调试到var data = await jsRuntime.InvokeAsync<string>("get", key);就终止,既无返回值也无报错,控制台没输出“Operator is get”。第二次调用代码如下:

var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token));
Guid operatorID = Guid.Parse(operatorToken.UserID);
Console.WriteLine("Operator is get");

请问为何第二次无法获取值,该如何修复?


分析与解决方案

可能原因1:异步上下文阻塞(死锁)

第二次调用的代码可能处于同步方法中,强行用.Result/.Wait()等待异步操作,导致.NET端的异步回调被阻塞。JS层虽然执行了get方法并打印日志,但.NET端无法继续执行后续代码,出现无响应的情况。

可能原因2:Token数据异常或空引用

第一次调用后,Token可能被意外清除、篡改,或者序列化/反序列化失败。此时GetAsync返回null,但调用代码直接访问operatorToken.UserID会抛出NullReferenceException,由于异常未被捕获且处于异步上下文,导致执行终止且无明显报错。

修复步骤

  1. 确保异步调用全程使用await
    必须在async方法中调用异步方法,禁止用.Result/.Wait()阻塞线程:

    // 错误示例(同步方法阻塞异步调用)
    public void SomeSyncMethod()
    {
        var token = localStorageService.GetAsync<Token>(nameof(Token)).Result; // 易导致死锁
    }
    
    // 正确示例
    public async Task SomeAsyncMethod()
    {
        var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token));
        // 先校验返回值
        if(operatorToken == null)
        {
            Console.WriteLine("Token不存在或已失效");
            return;
        }
        Guid operatorID = Guid.Parse(operatorToken.UserID);
        Console.WriteLine("Operator is get");
    }
    
  2. 添加异常捕获与数据校验
    给GetAsync方法和调用处增加异常处理与数据校验,定位问题:

    • 修改ILocalStorageService.cs:
      public async Task<T> GetAsync<T>(string key) where T : class
      {
          try
          {
              var data = await jsRuntime.InvokeAsync<string>("get", key);
              Console.WriteLine(".NET端获取数据:" + data); // 新增日志排查
              if (string.IsNullOrEmpty(data)) 
              { 
                  Console.WriteLine("LocalStorageService: token is null"); 
                  return null; 
              }
              return JsonSerializer.Deserialize<T>(data);
          }
          catch(Exception ex)
          {
              Console.WriteLine("LocalStorage获取失败:" + ex.Message);
              return null;
          }
      }
      
    • 修改第二次调用代码:
      var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token));
      if(operatorToken == null || string.IsNullOrEmpty(operatorToken.UserID))
      {
          Console.WriteLine("Token无效或不存在");
          return;
      }
      // 用TryParse避免格式错误抛出异常
      if(Guid.TryParse(operatorToken.UserID, out Guid operatorID))
      {
          Console.WriteLine("Operator is get,ID:" + operatorID);
      }
      else
      {
          Console.WriteLine("UserID格式错误");
      }
      
  3. 验证LocalStorage实际存储内容
    在Chrome控制台执行localStorage.getItem('Token'),检查返回的JSON是否有效、是否包含UserID字段。如果数据异常,排查第一次存储Token的代码是否正确序列化对象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:33:02