有没有办法递归等待 Javascript 中的值?
Is there a way to recursively await a value in Javascript?
我正在用 Javascript 制作一个项目,并且我有一个对象具有 returns 承诺的 getter。我可以用这段代码模拟这个对象:
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
}
这是一个有趣的情况。不,这里没有任何语法可以帮助您,您需要使用您的函数或类似函数。
我想出了一个方法让这个工作完全按照我想要的方式进行! await 语句不仅仅适用于 promises。它也适用于 thenables。 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);
})();
我正在用 Javascript 制作一个项目,并且我有一个对象具有 returns 承诺的 getter。我可以用这段代码模拟这个对象:
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
}
这是一个有趣的情况。不,这里没有任何语法可以帮助您,您需要使用您的函数或类似函数。
我想出了一个方法让这个工作完全按照我想要的方式进行! await 语句不仅仅适用于 promises。它也适用于 thenables。 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);
})();