异步/等待类构造函数 [英] Async/Await Class Constructor

查看:28
本文介绍了异步/等待类构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在尝试在类构造函数中使用 async/await.这样我就可以获得我正在处理的 Electron 项目的自定义 e-mail 标签.

At the moment, I'm attempting to use async/await within a class constructor function. This is so that I can get a custom e-mail tag for an Electron project I'm working on.

customElements.define('e-mail', class extends HTMLElement {
  async constructor() {
    super()

    let uid = this.getAttribute('data-uid')
    let message = await grabUID(uid)

    const shadowRoot = this.attachShadow({mode: 'open'})
    shadowRoot.innerHTML = `
      <div id="email">A random email message has appeared. ${message}</div>
    `
  }
})

`}})

At the moment however, the project does not work, with the following error:

然而,目前该项目不起作用,出现以下错误:

Class constructor may not be an async method

Is there a way to circumvent this so that I can use async/await within this?  Instead of requiring callbacks or .then()?

有没有办法绕过这个,以便我可以在其中使用 async/await?而不是需要回调或 .then()?

解决方案

推荐答案

永远行不通.

async 关键字允许在标记为 async 的函数中使用 await,但它也会将该函数转换为承诺生成器.所以标有 async 的函数将返回一个 promise.另一方面,构造函数返回它正在构造的对象.因此,我们有一种情况,您希望同时返回一个对象和一个承诺:一种不可能的情况.

You can only use async/await where you can use promises because they are essentially syntax sugar for promises. You can't use promises in a constructor because a constructor must return the object to be constructed, not a promise.

你只能在可以使用 promise 的地方使用 async/await,因为它们本质上是 promise 的语法糖.不能在构造函数中使用 promise,因为构造函数必须返回要构造的对象,而不是 promise.

There are two design patterns to overcome this, both invented before promises were around.

有两种设计模式可以解决这个问题,它们都是在 promise 出现之前发明的.

  1. Use of an init() function. This works a bit like jQuery's .ready(). The object you create can only be used inside it's own init or ready function:

  1. init() 函数的使用.这有点像 jQuery 的 .ready().您创建的对象只能在它自己的 initready 函数中使用:

Usage:

用法:

Implementation:

实施:


  • Use a builder. I've not seen this used much in javascript but this is one of the more common work-arounds in Java when an object needs to be constructed asynchronously. Of course, the builder pattern is used when constructing an object that requires a lot of complicated parameters. Which is exactly the use-case for asynchronous builders. The difference is that an async builder does not return an object but a promise of that object:

  • 使用构建器.我没有看到这在 javascript 中使用得太多,但是当需要异步构造对象时,这是 Java 中更常见的解决方法之一.当然,构建器模式是在构造需要大量复杂参数的对象时使用的.这正是异步构建器的用例.不同之处在于异步构建器不返回对象,而是返回该对象的承诺:

    Usage:

    用法:

    Implementation:

    实施:

    Implementation with async/await:

    使用 async/await 实现:

    class myClass { constructor (async_param) { if (typeof async_param === 'undefined') { throw new Error('Cannot be called directly'); } } static async build () { var async_result = await doSomeAsyncStuff(); return new myClass(async_result); } }

  • <块引用>

    注意:虽然在上面的例子中我们为异步构建器使用了 promise,但严格来说它们并不是必需的.您可以轻松编写一个接受回调的构建器.

    Note: although in the examples above we use promises for the async builder they are not strictly speaking necessary. You can just as easily write a builder that accept a callback.

    <小时>

    注意在静态函数中调用函数.

    这与异步构造函数无关,而是与关键字 this 的实际含义有关(对于使用自动解析方法名称的语言的人来说,这可能有点令人惊讶,即,不需要 this 关键字的语言).


    Note on calling functions inside static functions.

    This has nothing whatsoever to do with async constructors but with what the keyword this actually mean (which may be a bit surprising to people coming from languages that do auto-resolution of method names, that is, languages that don't need the this keyword).

    this 关键字指的是实例化的对象.不是班级.因此,您通常不能在静态函数中使用 this,因为静态函数没有绑定到任何对象,而是直接绑定到类.

    The this keyword refers to the instantiated object. Not the class. Therefore you cannot normally use this inside static functions since the static function is not bound to any object but is bound directly to the class.

    也就是说,在下面的代码中:

    That is to say, in the following code:

    class A {
        static foo () {}
    }
    

    你不能这样做:

    var a = new A();
    a.foo() // NOPE!!
    

    相反,您需要将其称为:

    instead you need to call it as:

    A.foo();
    

    因此,以下代码会导致错误:

    Therefore, the following code would result in an error:

    class A {
        static foo () {
            this.bar(); // you are calling this as static
                        // so bar is undefinned
        }
        bar () {}
    }
    

    要修复它,您可以将 bar 设为常规函数或静态方法:

    To fix it you can make bar either a regular function or a static method:

    function bar1 () {}
    
    class A {
        static foo () {
            bar1();   // this is OK
            A.bar2(); // this is OK
        }
    
        static bar2 () {}
    }
    

    这篇关于异步/等待类构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆