根據你的意見,你可能應該做任何其他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()'方法。 –