首页 > 解决方案 > 解析 JavaScript 代理对象中的承诺

问题描述

我正在尝试创建一个 JavaScript 代理,它允许我深入遍历对象的属性,但是当我运行一个方法时,我希望它返回一个带有新代理的承诺,让我可以深入遍历该对象。

例子:

const foo = createProxy()
const result = await foo.any.number.of.properties.deep()
const result2 = await result.foo.bar()
const result3 = await result2.off.we.go.again()

我已经尝试创建一个函数的代理,当我想从方法调用同步返回代理时,这可以工作,但是当我尝试返回一个承诺时,它会无限循环。

但是,当我捕获一个then属性并尝试运行回调以将代理传递给它时,我会以无限循环中断浏览器。

const createProxy = <T>(path) => {
  return new Proxy(function () {}, {
    apply(_target, _thisArg, _args) {
      console.log("exec", path);
      return createProxy([]);
    },
    get(_target, key) {
      if (key === "then") {
        return (cb) => {
          cb(createProxy([...path, key]));
        };
      }
      return createProxy([...path, key]);
    },
  });
};

标签: javascript

解决方案


您履行承诺的对象不能是另一个 thenable - 否则resolve()算法将尝试等待该嵌套承诺。

在您的情况下,最简单的选择是从方法调用返回一个通过代理实现的承诺,而不是承诺的代理,并使您的代理不可使用:

function createProxy<T>(path = []) {
  return new Proxy(function () {
    console.log("exec", path);
    return Promise.resolve(createProxy([]));
  }, {
    get(_target, key) {
      if (typeof key === 'string' && key !== "then")
        return createProxy([...path, key]);
      else
        return Reflect.get(...arguments);
    },
  });
}

顺便说一句,请注意,await为了工作,您甚至不需要从方法调用中返回承诺 - 正常值也可以。只需确保它不可用,或者它的then方法按要求工作。


推荐阅读