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

如何阻止特定Promise内部调用指定函数 避免JavaScript库出现无限循环

解决方案

方案1:使用AsyncLocalStorage(推荐)

现代浏览器(Chrome 89+、Firefox 88+、Safari 15.4+)和Node.js都内置了AsyncLocalStorage API,专门用于跨异步调用链传递上下文,完全不受await、定时器、Promise回调的影响,完美适配你的场景。
实现示例:

// Node.js环境引入
import { AsyncLocalStorage } from 'node:async_hooks';
// 低版本浏览器可以引入core-js的polyfill实现兼容
const asyncLocalStorage = new AsyncLocalStorage();

async function fireUserCallbacks() {
  // 在当前异步执行链内存入阻止调用标记,整个异步上下文都可以读取到
  return asyncLocalStorage.run(true, async () => {
    // 执行用户的异步回调
    await new Promise(r => setTimeout(r, 1000));
  });
}

function foo() {
  if (asyncLocalStorage.getStore() === true) {
    throw new Error('禁止在回调内部调用foo,请使用专门的递归处理函数');
  }
  // 原有foo逻辑
}

验证效果符合预期:

foo(); // 外部直接调用正常执行
fireUserCallbacks();
foo(); // 不会被误拦截
fireUserCallbacks().then(() => foo()); // 回调执行完毕后调用也正常

方案2:适配现有资源加载逻辑的改造方案

你现有代码已经实现了RecursionTracker机制,只需要搭配AsyncLocalStorage做一层校验即可:

  1. 首先修改loadAsset方法,新增调用校验:
async loadAsset(assetId, recursionTracker = null) {
  // 新增校验逻辑
  if (recursionTracker === null) {
    const activeTracker = asyncLocalStorage.getStore();
    if (activeTracker) {
      throw new Error('禁止在generateAsset内部直接调用loadAsset,请使用recursionTracker.loadAsset处理嵌套资源加载');
    }
  }
  // 原有逻辑不变
  // ...
}
  1. 调用generateAsset前存入当前的跟踪器实例:
const assetData = await asyncLocalStorage.run(recursionTracker, () => asset.generateAsset(recursionTracker));

用户在generateAsset内部如果忘记用提供的递归处理方法,直接调用loadAsset会立刻触发警告,从根源上避免无限递归。

方案3:兼容低版本环境的计数方案

如果需要适配不支持AsyncLocalStorage的运行环境,可以用计数器替代布尔标记,仅适合fireUserCallbacks无并发执行的场景:

let preventFooCallCount = 0;

async function fireUserCallbacks() {
  preventFooCallCount++;
  try {
    // 执行用户异步回调
    await new Promise(r => setTimeout(r, 1000));
  } finally {
    preventFooCallCount--;
  }
}

function foo() {
  if (preventFooCallCount > 0) throw new Error();
  // 原有foo逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:06:04