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

Navigator.locks报错:回调不可运行,Vue API服务并发问题排查

问题分析与解决办法

错误原因

你遇到的Failed to execute 'invoke' on 'LockGrantedCallback': The provided callback is no longer runnable.错误,本质是浏览器锁机制在授予锁时,发现对应的回调函数已经不可用(比如被垃圾回收、上下文丢失)。结合你的代码场景,核心问题出在每次调用myfunc时都会创建一个新的匿名箭头回调,当多个组件首次加载同时请求锁、等待队列较长时,早期创建的回调可能因JS垃圾回收机制被标记为不可用。

修复方案

1. 抽离回调逻辑为服务方法,保持回调引用稳定

把锁内部的逻辑抽成服务类的独立方法,避免每次调用myfunc都生成新的匿名函数,确保锁回调的引用始终有效:

class MyService {
  // ... 其他现有代码

  // 抽离数据获取逻辑为独立方法
  async _fetchDataIfNeeded() {
    if (isNil(store.data)) {
      await this.updateToken();
      const response = await Get(dataUrl, this.token.accessToken);
      store.data = response.data;
    }
  }

  async myfunc() {
    // 用稳定的方法引用作为锁回调
    await navigator.locks.request("data", () => this._fetchDataIfNeeded());
    return store.data;
  }
}

2. 添加错误捕获与重试机制

针对锁回调失效的异常,增加捕获逻辑并重试,避免因单次错误导致数据缺失:

async myfunc() {
  try {
    await navigator.locks.request("data", () => this._fetchDataIfNeeded());
  } catch (err) {
    console.error("锁请求失败:", err);
    // 针对回调失效的错误进行重试
    if (err.message.includes("no longer runnable")) {
      await navigator.locks.request("data", () => this._fetchDataIfNeeded());
    }
  }
  return store.data;
}

3. 验证updateToken的上下文正确性

确保updateToken方法的this指向正确的MyService实例:

  • 如果updateToken是类的普通方法,建议改为箭头函数定义,避免上下文丢失:
    updateToken = async () => {
      // 你的token更新逻辑
    }
    

额外检查点

  • 确认store.data的初始化状态,确保首次调用时确实为nil,没有被其他逻辑提前修改
  • 验证Get请求的可靠性,排除因网络请求失败导致的数据缺失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:05:23