我正在try 为JavaScript类(我的应用程序中的控制器)编写一个"混合",在实际调用实际方法之前,自动"等待"给定的函数被解析.实类方法应接收解析值作为最后一个参数.

这是useAwait的代码,我在这里寻找静态类属性awaits,并将originalFunc包装成一个新的async.我调用新函数,将原始参数plus传递给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;
  }
}

problem:对于foo(已经是async)来说一切似乎都很好,但对于bar来说不是这样:结果是Promise,因为现在bar被包装在async中(之前没有).我知道异步函数结果被包装到Promise中.Codepen example其中bar个调用输出"[对象promise ]".

所以question是:理论上,我应该判断原始函数是否为async,如果不是,返回值为await

推荐答案

...理论上,我应该判断原始函数是否为async,如果不是,返回值为await?"

没关系,你的包装纸是asyncasync函数always返回promise ,无论是否使用await.此外,包装器can't是同步的,因为它需要调用awaitFn(本例中为load)并等待其结果.

如果要包装originalFunction(bar),使其等待awaitFn(load)完成,则包装后的版本需要是异步的(async或显式返回promise [或接受回调,但最好使用promise ]).它不能同步,因为awaitFn(load)不同步.

如果在构建类实例时它还没有准备好使用,那么可以考虑使用静态方法来获取实例;静态实例将返回一个promise ,即一旦load完成,它将与实例一起实现.草图:

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相关问答推荐

从所选的select jQuery中删除多个属性

JavaScript代理不适用于打开的窗口对象

为什么在获取回调内设置状态(不会)会导致无限循环?

React Hooks中useState的同步问题

Phaser框架-将子对象附加到Actor

node TS:JWT令牌签名以验证客户端和后台问题之间的身份验证

为什么这个JS模块在TypeScript中使用默认属性导入?""

如何禁用附加图标点击的v—自动完成事件

在react js中使用react—router—dom中的Link组件,分配的右侧不能被 destruct ''

cypress中e2e测试上的Click()事件在Switch Element Plus组件上使用时不起作用

使用JQuery单击元素从新弹出窗口获取值

确保函数签名中的类型安全:匹配值

扩展类型的联合被解析为基类型

Reaction组件在本应被设置隐藏时仍显示

Jest toHaveBeenNthCalledWith返回当前设置的变量值,而不是调用时的值

如何防止ionic 输入中的特殊字符.?

Next.js中的服务器端组件列表筛选

如何使用画布在另一个内部绘制一个较小但相同的形状,同时保持恒定的边界厚度?

使用RxJS from Event和@ViewChild vs KeyUp事件和RxJS主题更改输入字段值

ReferenceError:无法在初始化之前访问setData