目前,我正在尝试async/await在类构造函数中使用。这样一来,我就可e-mail以为正在从事的Electron项目获取自定义标签。
async/await
e-mail
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> ` } })
但是,目前该项目无法正常工作,并出现以下错误:
Class constructor may not be an async method
有没有办法避免这种情况,以便我可以在其中使用异步/等待?而不需要回调或.then()?
这 永远 行不通。
该async关键字允许await在标记为函数中使用async,但它也是功能转换成一个承诺发生器。因此,标有的函数async将返回承诺。另一方面,构造函数返回其正在构造的对象。因此,在这种情况下,您既要返回对象又要兑现承诺:一种不可能的情况。
async
await
您只能在可以使用诺言的地方使用async / await,因为它们本质上是诺言的语法糖。您不能在构造函数中使用promise,因为构造函数必须返回要构造的对象,而不是promise。
有两种设计模式可以克服这一问题,它们都是在实现承诺之前发明的。
init()
.ready()
init
ready
用法:
var myObj = new myClass(); myObj.init(function() { // inside here you can use myObj });
实现方式:
class myClass { constructor () { } init (callback) { // do something async and call the callback: callback.bind(this)(); } }
myClass.build().then(function(myObj) { // myObj is returned by the promise, // not by the constructor // or builder }); // with async/await: async function foo () { var myObj = await myClass.build(); }
class myClass { constructor (async_param) { if (typeof async_param === 'undefined') { throw new Error('Cannot be called directly'); } } static build () { return doSomeAsyncStuff() .then(function(async_result){ return new myClass(async_result); }); } }
用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,但严格来讲它们并不是必需的。您可以轻松地编写一个接受回调的构建器。
这与异步构造函数无关,而与关键字的this实际含义无关(这对于使用自动解析方法名称的语言(即不需要this关键字的语言)来的人来说可能有点令人惊讶。
this
的this关键字是指实例化的对象。不是班级。因此,您通常不能this在内部静态函数中使用,因为静态函数未绑定到任何对象,而是直接绑定到该类。
也就是说,在以下代码中:
class A { static foo () {} }
您不能:
var a = new A(); a.foo() // NOPE!!
相反,您需要将其称为:
A.foo();
因此,以下代码将导致错误:
class A { static foo () { this.bar(); // you are calling this as static // so bar is undefinned } bar () {} }
要修复它,您可以bar使用常规函数或静态方法:
bar
function bar1 () {} class A { static foo () { bar1(); // this is OK A.bar2(); // this is OK } static bar2 () {} }