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.
Then it is not possible to use an asynchronous function like
getBlobUrlin there. You can never make this work, it's completely impossible.Instead, you will need to redesign your approach. Evaluate the conditions and do the async requests before calling
marked. Then pass in the data that you can render synchronously.