То, что я делаю, используется fs, чтобы сшить 5 частей html-страниц (html, head, chead, topaside, main, footer
) вместе. Имя файла: htmlpage.js
, поэтому вы можете просто запустить node htmlpage.js file1 file2 file3 ...
в инструменте командной строки, и он будет сшивать эти части html-страницы вместе, а затем выплюнуть file1.html, file2.html, file3.html ...
. Я не люблю использовать механизм шаблонов/библиотеку/фреймворк или что-то еще, особенно когда я учусь.
Вот код Sorce:Node.js, как итерации с асинхронным обратным вызовом?
'use strict';
const fs = require('fs'),
head = fs.createReadStream('./html-parts/head.html', 'utf8'),
topaside = fs.createReadStream('./html-parts/topaside.html', 'utf8'),
footer = fs.createReadStream('./html-parts/footer.html', 'utf8');
let name = process.argv.slice(2),
htmlray = [],
ni = 0,
nl = name.length;
for (ni; ni < nl; ni ++) {
let cheadP = './html-parts/' + name[ni] + '-head.html',
mainP = './html-parts/' + name[ni] + '-main.html',
htmlP = name[ni] + '.html',
chead = fs.createReadStream(cheadP, 'utf8'),
main = fs.createReadStream(mainP, 'utf8'),
html = fs.createWriteStream(htmlP, 'utf8');
//let those parts form an array
htmlray = [html, head, chead, topaside, main, footer];
openendPipe(htmlray[1], htmlray[0]);
htmlray[1].on('end',() => {
openendPipe(htmlray[2], htmlray[0]);
htmlray[2].on('end',() => {
openendPipe(htmlray[3], htmlray[0]);
htmlray[3].on('end',() => {
openendPipe(htmlray[4], htmlray[0]);
htmlray[4].on('end',() => {
htmlray[5].pipe(htmlray[0]);
htmlray[5].on('end',() => {
console.log(name + '.html' + ' created');
});
});
});
});
});
}
function openendPipe(src, dst) {
return src.pipe(dst, {end: false});
}
Но что, если htmlray
имеет 100 частей, я хочу, чтобы иметь возможность делать итерации, чтобы заменить эту коду, давайте назовем его pipeblock
:
openendPipe(htmlray[1], htmlray[0]);
htmlray[1].on('end',() => {
openendPipe(htmlray[2], htmlray[0]);
htmlray[2].on('end',() => {
openendPipe(htmlray[3], htmlray[0]);
htmlray[3].on('end',() => {
openendPipe(htmlray[4], htmlray[0]);
htmlray[4].on('end',() => {
htmlray[5].pipe(htmlray[0]);
htmlray[5].on('end',() => {
console.log(name + '.html' + ' created');
});
});
});
});
});
Я пробовал эти решения, они не работали:
решение 1:
(function() {
let i = 0, count = 1;
function nextpipe() {
let arr = arguments[0];
i ++;
if (count > 5) return;
openendPipe(arr[i], arr[0]);
count ++;
arr[i].on('end', nextpipe);
}
return nextpipe;
})();
//then replace 'pipeblock' with 'nextpipe(htmlray)';
//console.log: nextpipe is undefined.
Решение 2:
//replace 'pipeblock' with these code
let pi = 1,
pl = htmlray.length - 1;
htmlray[pi].pipe(htmlray[0], {end: false});
htmlray[pi].on('end', nextpipe);
function nextpipe() {
if (pi > pl) return console.log(name + '.html' + ' created');;
pi ++;
htmlray[pi].pipe(htmlray[0], {end: false});
htmlray[pi].on('end', nextpipe);
}
//cosole.log:
//htmlray[pi].pipe(htmlray[0], {end: false});
//TypeError: Cannot read property 'pipe' of undefined
Да, я смотрел пару видеороликов и время от времени читал документацию о обещании и генераторе, но каждый раз я их увольнял. Ну, если это единственное решение, но не итерация, я думаю, я должен попробовать их. Спасибо за напоминание. – alexcres
Я потерял много времени сам год или два назад, пытаясь пропустить этот материал (и я действительно сожалею об этом), и пытаюсь поэкспериментировать с циклами обратного вызова, асинхронными водопадами и т. Д. - обещания - изящное и мощное решение. И уже с обработкой ошибок (это также должно быть важно) - просто добавьте '.catch()' к вам окончательное обещание. –
Waite, я просто помню, что для моего вопроса об асинхронном обратном вызове 100 раз, в обещании, вам все равно нужно использовать then() для следующего вызова 100 раз. А в генераторе вам все равно нужно получить 100 раз. Я прав? Я действительно не хочу этого делать. – alexcres