JavaScript 将现有函数包装在异步函数中 : deal with the result (automatically wrapped into a Promise)?

标签 javascript async-await

我正在尝试为 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/

相关文章:

javascript - Jquery 获取触发事件的实际控件。

javascript - 如何使用javascript获取表格中的所有Div

javascript - React useEffect hook 和 Async/await 自己的获取数据函数?

c# - query.wait 没有完成

javascript - Lite-Javascript Gallery - 我可以绝对定位 img 与 <li> 的关系吗?

javascript - 单击按钮即可 knockout 提交绑定(bind)

c# - 在嵌套异步方法中使用 ConfigureAwait

javascript - 如何使用 async/await 将此回调转换为 promise?

javascript - 帖子正文中缺少必需参数 To

javascript - 异步/等待执行是否比 setTimeout 回调具有更高的优先级?