根据你的意见,你可能应该做任何其他HTMLElement的资产加载:做构造函数启动一个sideloading动作,根据结果产生一个负载或错误事件。
是的,这意味着使用承诺,但它也意味着“以与其他HTML元素相同的方式进行操作”,因此您身处公司。例如:
var img = new Image();
img.onload = function(evt) { ... }
img.addEventListener("load", evt => ...);
img.onerror = function(evt) { ... }
img.addEventListener("error", evt => ...);
img.src = "some url";
此序幕源资产的是,当它成功,在onload
结束,当它出了毛病,在onerror
结束的异步负载。所以,让自己的类就此别过:
class EMailElement extends HTMLElement {
constructor() {
super();
this.uid = this.getAttribute('data-uid');
}
setAttribute(name, value) {
super.setAttribute(name, value);
if (name === 'data-uid') {
this.uid = value;
}
}
set uid(input) {
if (!input) return;
const uid = parseInt(input);
// don't fight the river, go with the flow
let getEmail = new Promise((resolve, reject) => {
yourDataBase.getByUID(uid, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
// kick off the promise, which will be async all on its own
getEmail()
.then(result => {
this.renderLoaded(result.message);
})
.catch(error => {
this.renderError(error);
});
}
};
customElements.define('e-mail', EmailElement);
然后你让renderLoaded/renderError功能处理事件调用和阴影DOM:
renderLoaded(message) {
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<div class="email">A random email message has appeared. ${message}</div>
`;
// is there an ancient event listener?
if (this.onload) {
this.onload(...);
}
// there might be modern event listeners. dispatch an event.
this.dispatchEvent(new Event('load', ...));
}
renderFailed() {
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<div class="email">No email messages.</div>
`;
// is there an ancient event listener?
if (this.onload) {
this.onerror(...);
}
// there might be modern event listeners. dispatch an event.
this.dispatchEvent(new Event('error', ...));
}
另外请注意,我改变你的id
到class
,因为除非您编写一些奇怪的代码,以便在页面上只允许单个实例的<e-mail>
元素,否则不能使用唯一标识符,然后将其分配给一组元素。
构造函数的目的就是为了你分配一个对象,然后立即返回。你可以更具体地了解*为什么*你认为你的构造函数应该是异步的?因为我们几乎可以保证在这里处理[XY问题](https://meta.stackexchange.com/a/66378)。 –
@ Mike'Pomax'Kamermans这很可能。基本上,我需要查询数据库才能获取加载此元素所需的元数据。查询数据库是一个异步操作,因此我需要一些方法来在构造元素之前等待它完成。我宁愿不使用回调,因为我在整个项目的其余部分都使用了等待/异步,并希望保持连续性。 –
@ Mike'Pomax'Kamermans这是一个电子邮件客户端,其中每个HTML元素看起来都类似于'',并且使用'customElements .define()'方法。 –