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

JavaScript中Proxy对象作为异步返回值时Promise无法resolve问题

问题根因

你的猜测完全正确,问题核心就是Promise的决议机制和你的Proxy实现冲突了:

  • 所有async函数返回值都会被隐式传入Promise.resolve()处理,最终决议给外层调用者
  • Promise.resolve()的规则是:如果传入的值是thenable对象(即带有then方法的对象),会自动调用这个then方法,传入resolve、reject两个回调函数,等待这个thenable主动调用回调完成决议
  • 你的Proxy的get捕获器对任何属性访问都返回一个函数,这就导致访问proxy.then时也返回了函数,被识别为thenable。但你返回的这个then函数只会返回test${x}字符串,完全没有调用传入的resolve回调,所以外层的Promise永远等不到决议信号,就一直处于pending状态。

修复方案

根据你的业务需求二选一即可:

方案1:排除then属性的捕获(业务不需要调用controller.then()时用)

修改Proxy的get捕获器,访问then时直接返回undefined,让Promise不会把它识别为thenable:

let x = 0;
function getController() {
  return new Proxy({}, {
    get: (target, prop) => {
      if (prop === 'then') return undefined;
      return () => `test${x++}`;
    }
  });
}
// 剩余代码保持不变即可

方案2:兼容controller.then()业务调用同时解决Promise决议问题

如果业务确实需要支持调用controller.then()方法,需要判断调用then时的入参是否是Promise传入的决议回调,如果是就直接决议当前Proxy对象:

let x = 0;
function getController() {
  const proxyTarget = {};
  return new Proxy(proxyTarget, {
    get: (target, prop) => {
      if (prop === 'then') {
        return (onFulfilled) => {
          // 如果是Promise的决议回调,直接resolve当前proxy
          if (typeof onFulfilled === 'function') {
            onFulfilled(proxyTarget);
            return;
          }
          // 否则走业务逻辑
          return `test${x++}`;
        }
      }
      return () => `test${x++}`;
    }
  });
}
// 剩余代码保持不变即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:27:05