Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
WIP. Потоковая выдача html через генераторы
function isGenerator(target) {
return target[Symbol.toStringTag] === 'GeneratorFunction';
}
function isIterable(obj) {
if (obj === null || obj === void 0) {
return false;
}
if (typeof obj === 'string') {
return false;
}
return typeof obj[Symbol.iterator] === 'function';
}
function html(strings, ...values) {
const items = strings.reduce((acc, item, index) => {
acc.push(item);
if (index < values.length) {
acc.push(values[index]);
}
return acc;
}, []).filter(Boolean);
return function* (context) {
for (const item of items) {
switch (true) {
case (isIterable(item)): {
yield* item;
break;
}
case (item instanceof Function): {
const res = item(context);
if (isIterable(res)) {
yield* res;
} else {
yield res;
}
break;
}
case (item instanceof Promise): {
item.then((res) => {
yield res;
})
}
default: {
yield item;
}
}
}
}
}
const headerTemplate = html`
<header>
<h1>Header Title</h1>
</header>
`;
const footerTemplate = html`
<footer>
footer
</footer>
`;
const mainTemplate = html`
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${ctx => ctx.title}</title>
</head>
<body>
${headerTemplate()}
<nav>
<ul>${[
`<li><a href="#">Home</a></li>`,
`<li><a href="#">Solutions</a></li>`,
`<li><a href="#">Blog</a></li>`,
`<li><a href="#">Career</a></li>`,
`<li><a href="#">Contacts</a></li>`,
]}</ul>
</nav>
<main>${ctx => ctx.main}</main>
${footerTemplate()}
</body>
</html>
`;
function delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
require('http')
.createServer(async (req, res) => {
const ctx = {
title: 'some top title',
main: 'body'
}
res.writeHead(200, {
'Content-Type': 'text/html'
});
for (let chunk of mainTemplate(ctx)) {
res.write(chunk);
await delay(1000);
}
res.end();
}).listen(3000, () => {
console.log('http://localhost:3000')
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.