I am implementing a custom render function for marked which will check a few conditions on images, does an async request and then returns an image from a different source. However, since the new request is asynchronous, I will only ever get a promise back instead of a "real" image url.
attachmentService.getBlobUrl is an async function which does an http request and returns a promise.
My render function looks like this:
marked.use({
renderer: {
image: (src, title, text) => {
if (someCondition) {
// Some code of parsing the src attribute
// ...
return this.attachmentService.getBlobUrl(attachment)
.then(url => {
return Promise.resolve(`<img src="${url}" alt="${text}" title="${title}"/>`)
})
}
return `<img src="${src}" alt="${text}" title="${title}"/>`
},
}
})
I already tried returning the image tag directly:
// ...
return this.attachmentService.getBlobUrl(attachment)
.then(url => {
return `<img src="${url}" alt="${text}" title="${title}"/>`
})
// ...
I have also tried wrapping the function in an async call and returning that (not wrapped in a Promise.resolve):
// ...
return (async () => {
return await this.attachmentService.getBlobUrl(attachment)
.then(url => {
return `<img src="${url}" alt="${text}" title="${title}"/>`
})
})()
// ...
However, this also only gives me a promise.
I cannot use await because the render function itself must be synchronous - that's not something I have control over.
You can defer your asynchronous operation:
classname to the img elements that should be treated differently. You could also change thesrcattribute to some loading image.MutationObserverand only listen for those elements getting added. In the MutationObserver's callback you can then perform your asynchronous operation and update the element'ssrc.