我正在尝试为 JavaScript 类( Controller ,在我的应用程序中)编写一个“混合”,以在实际调用真正的方法之前自动“等待”给定的函数得到解析。真正的类方法应该接收解析值作为最后一个参数。
这是 useAwait
的代码,我在其中查找静态类属性 await
并将 originalFunc
包装到新的 异步
一。我正在调用新函数,传递原始参数加上 asyncFn
调用结果:
const useAwait = (controller, asyncFn) => {
controller.constructor.awaits.forEach(func => {
const originalFunc = controller[func];
controller[func] = async (...args) => {
return originalFunc.apply(
controller,
[...args, await asyncFn.call(controller)]
);
};
});
}
因此,当在此类实例上调用 useAwait(ctrl, this.load)
时:
class Controller {
static awaits = ['foo', 'bar'];
promise;
constructor() {
useAwait(this, this.load);
}
async foo(e, resolved) {
return resolved;
}
bar(resolved) {
return resolved;
}
async load() {
if (!this.promise) {
this.promise = new Promise(resolve => setTimeout(() => {
resolve('Hello World!');
}, 3000));
}
return this.promise;
}
}
问题:对于foo
(已经是async
)来说一切似乎都很好,但对于bar
来说却不是:结果是一个 Promise
,因为现在 bar
被包装在 async
中(以前没有)。我知道异步函数结果被包装到 Promise 中。 Codepen example其中 bar
调用输出“[object Promise]”。
所以问题是:理论上,我应该检查原始函数是否async
,如果不是,await
,因为它是返回值?
最佳答案
...in theory, I should check if the original function is
async
and if it was not,await
for it's return value?"
没关系,你的包装器是异步的; async
函数总是返回一个 promise ,无论您是否使用await
。此外,您的包装器不能是同步的,因为它需要调用awaitFn
(在示例中为load
)并等待其结果。
如果您要包装 originalFunction
(bar
),使其等待 awaitFn
(load
)才能完成,它的包装版本需要是异步的(async
,或者显式返回一个 promise [或接受回调,但恕我直言,使用 promise 更好])。它不能是同步的,因为 awaitFn
(load
) 不是同步的。
如果类实例在构造时尚未准备好使用,您可以考虑使用静态方法来获取实例;静态实例将返回一个 promise ,一旦 load
完成,该实例就会履行该 promise 。粗略草图:
class Controller {
dataFromLoadingProcess;
constructor(dataFromLoadingProcess) {
this.dataFromLoadingProcess = dataFromLoadingProcess;
}
async foo(e, resolved) {
// ...optionally use `this.dataFromLoadingProcess`...
return resolved;
}
bar(resolved) {
// ...optionally use `this.dataFromLoadingProcess`...
return resolved;
}
static async createInstance() {
await /*...the loading process...*/;
return new Controller(/*...data from loading process here, perhaps...*/)
}
}
关于JavaScript 将现有函数包装在异步函数中 : deal with the result (automatically wrapped into a Promise)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72951831/