Библиотека Marked позволяет преобразовывать Markdown в HTML с высокой скоростью и гибкостью. Для работы с асинхронным API важно корректно настроить парсер и понимать, какие функции поддерживают асинхронную обработку.
Установка производится через npm:
npm install marked
Импорт в модуле ES6:
import { marked } from 'marked';
Для работы с асинхронными функциями необходимо использовать
marked.parse с передачей функции обратного вызова или
промиса, так как синхронный метод marked.parse блокирует
выполнение и не подходит для асинхронных источников данных.
Асинхронное API Marked позволяет использовать пользовательские функции рендеринга и загрузки контента. Основной метод:
await marked.parse(markdownString, options);
Возможность асинхронной обработки важна при динамическом формировании
ссылок, изображений или вставке данных из внешних API. Для этого
используется кастомный Renderer:
const renderer = {
async image(href, title, text) {
const optimizedSrc = await fetchOptimizedImage(href);
return `<img src="${optimizedSrc}" alt="${text}" title="${title || ''}">`;
},
async link(href, title, text) {
const validatedHref = await validateLink(href);
return `<a href="${validatedHref}" title="${title || ''}">${text}</a>`;
}
};
const html = await marked.parse(markdownString, { renderer });
Ключевой момент — методы рендерера могут быть асинхронными, и
marked.parse корректно ожидает их выполнение.
Tokenizers позволяют добавлять или изменять правила парсинга Markdown. Для асинхронного использования можно комбинировать токенизатор с внешними запросами:
const tokenizer = {
async link(src) {
const match = src.match(/\[([^\]]+)\]\(([^)]+)\)/);
if (!match) return;
const [ , text, href ] = match;
const resolvedHref = await resolveDynamicLink(href);
return {
type: 'link',
raw: match[0],
text,
href: resolvedHref
};
}
};
const html = await marked.parse(markdownString, { tokenizer });
Токенизатор может выполнять любые асинхронные операции, включая сетевые запросы, при этом сохраняется корректная последовательность парсинга.
Marked поддерживает хуки на различных этапах рендеринга. Для асинхронного API ключевые хуки:
walkTokens: асинхронный обход токенов перед
рендерингом.async walkTokens: возможность трансформировать или
фильтровать токены с ожиданием внешних данных.Пример использования walkTokens для асинхронной
обработки:
const options = {
async walkTokens(token) {
if (token.type === 'image') {
token.href = await optimizeImage(token.href);
}
if (token.type === 'link') {
token.href = await validateLink(token.href);
}
}
};
const html = await marked.parse(markdownString, options);
Важно понимать, что асинхронные хуки позволяют выполнять модификацию токенов до их финального преобразования в HTML без блокировки основного потока.
Для больших документов или потоковых данных можно использовать
marked.lexer и асинхронные функции обработки:
const tokens = marked.lexer(markdownStream);
for (const token of tokens) {
if (token.type === 'link') {
token.href = await resolveLink(token.href);
}
}
const html = marked.parser(tokens);
Такой подход минимизирует задержки при работе с внешними API и позволяет обрабатывать большие объемы данных по частям.
Асинхронное API Marked особенно полезно при:
Все операции могут быть встроены в единый асинхронный поток, где
await marked.parse() обеспечивает корректный порядок
выполнения, а кастомные рендереры и токенизаторы позволяют гибко
управлять финальным HTML-контентом.
Для асинхронного использования рекомендуется:
walkTokens вместо полного рендерера, если
модификации минимальны.Promise.all.Эти подходы позволяют сохранять высокую скорость парсинга и одновременно использовать асинхронные источники данных без блокировки.