有没有一种方法可以递归地等待Java中的值?

时间:2020-03-27 17:29:20

标签: javascript asynchronous async-await es6-promise

我正在用Javascript创建一个项目,并且我有一个对象,该对象的getter返回promises。我可以用以下代码嘲笑该对象:

async function asyncifiedObject(object) {
  let o = {};

  let keys = [...Object.keys(object)];
  for (let item of keys) {
    o.__defineGetter__(item, async () => {
      if (object && object[item]) {
        if (typeof object[item] == "object") {
          // Do other async things, like network requests, etc.
          return await asyncifiedObject(object[item]);
        } else {
          return object[item];
        }
      }
    });
  }
  return o;
}

我得到了这些对象之一:

let o=asyncifiedObject({hello:{world:{it:{is:{nice:{out:"today"}}}}}})

当我访问该对象的专有属性时,我目前正在await (await (await (await (await (await (await o).hello).world).it).is).nice).out进行操作,但这很长而且看起来很可怕。

我可以像await getAsyncValues(o,"hello","world","it","is","nice","out")那样使用函数来执行此操作,但是我想做的是await o.hello.world.it.is.nice.out之类的操作,但这是行不通的,因为需要等待所有的承诺,而不是只是第一个。有什么可行的方法吗?

顺便说一下,这是getAsyncValues的示例实现:

async function getAsyncValues(object,...values){
  let r=object;
  for(let value of values){
    r=(await r)[value]
  }
  return r
}

2 个答案:

答案 0 :(得分:1)

这是一个有趣的情况。不,没有什么语法可以帮助您,您需要使用函数或类似功能。

答案 1 :(得分:0)

我想出了一种完全按照我想要的方式进行这项工作的方法!等待声明,不只是与承诺一起工作。它也适用于罐头。 thenable是具有Promise式then方法的对象。我修改了getAsyncValues,下面是最终代码。

(async () => {
  async function asyncifiedObject(object) {
    let o = {};

    let keys = [...Object.keys(object)];
    for (let item of keys) {
      o.__defineGetter__(item, async () => {
        if (object && object[item]) {
          if (typeof object[item] == "object") {
            // Do other async things, like network requests, etc.
            return thenableHack(await asyncifiedObject(object[item]));
          } else {
            return object[item];
          }
        }
      });
    }
    return o;
  }

  function thenableHack(object, ...values) {
    let o = {
      then: async e => {
        let r = object;
        for (let value of values) {
          r = (await r)[value];
        }
        e(r);
      },
      catch: () => {}
    };
    return new Proxy(o, {
      get: (o, p) => {
        return o[p] || thenableHack(object, ...values, p);
      }
    });
  }

  let o = thenableHack(
    asyncifiedObject({
      hello: { world: { it: { is: { nice: { out: "today" } } } } }
    })
  );
  console.log(await o.hello.world.it.is.nice.out);
})();