#javascript #node.js
#javascript #node.js
Вопрос:
Короче говоря: у меня есть функция обратного вызова, которая имеет строковый параметр и должна возвращать строку. Мне нужно преобразовать эту строку, используя библиотеку, которая работает только с потоками. Как мне это сделать?
Дольше: я использую Node.js replacestream, который имеет функцию для сопоставления с регулярным выражением и так же, как String.replace, позволяет указать функцию обратного вызова для замены. Что мне нужно сделать, это взять соответствующую строку, запустить ее через другую библиотеку, а затем вернуть преобразованную строку для замены.
Проблема в том, что эта библиотека работает только с потоками. Обычно я мог бы сделать все это асинхронным, но я не вижу никакого способа сделать это с помощью обратного вызова String.replace .
src(['*.js'])
.pipe(replace(/`(.*?)`/gs, function(match, p1, offset, string) {
var ostream = stringtostream(p1);
ostream.pipe(glslminify());
//???code that waits for ostream to finish and converts it to string???
return string_from_ostream;
}))
.pipe(dest(jsdest));
Должен быть лучший способ сделать это, поэтому я ищу любые предложения.
Комментарии:
1. Эта библиотека: github.com/TimvanScherpenzeel/glsl-minifier
2. Я смотрю… Он состоит из 4 разных вложенных библиотек, и по крайней мере у 2 из них есть способ сделать это синхронно, так что это полностью решило бы мою проблему, если бы все 4 из них могли это сделать.
3. К сожалению, этот кажется асинхронным: npmjs.com/package/glsl-min-stream
Ответ №1:
Вы пояснили, что библиотека использует поток и, что важно, выполняет свою работу асинхронно. Это означает, что вы не можете использовать его непосредственно в replace
обратном вызове для определения возвращаемого значения обратного вызова, поскольку, конечно, это должно предоставляться синхронно.
Вместо этого вы можете сделать свою функцию асинхронной, разбить строку на части, которые нуждаются в обработке, и части, которые этого не делают, запустить асинхронную обработку частей, которые нуждаются в обработке, а затем собрать завершенную строку, когда это будет сделано.
Вот пример использования резервного асинхронного процесса, который сообщает о завершении с помощью обещаний (вы можете обернуть обещание вокруг потока или адаптировать код для использования завершения потока вместо этого):
// Your function for processing the string
function yourFunction(str) {
return Promise.all(
str.split(/`(.*?)`/s).map((fragment, index) =>
// The capture groups are the odd-numbered indexes
index % 2 === 1
? process(fragment)
: fragment
)
)
.then(segments => segments.join(""));
}
// The promise wrapper around the library
function process(str) {
return new Promise((resolve, reject) => {
// Emulate via timer; I'm not emulating failure here, but
// you'd handle failure by calling `reject`
setTimeout(() => {
// Success
resolve(str.toUpperCase());
}, Math.random() * 400);
});
}
// Testing with and without leading and trailing text
yourFunction("`one two three` testing `two three four`")
.then(result => {
console.log(result);
return yourFunction("leading text `one two three` testing `two three four`")
})
.then(result => {
console.log(result);
return yourFunction("leading text `one two three` testing `two three four` trailing text")
})
.then(result => {
console.log(result);
})
.catch(error => {
// Handle/report error
});
Комментарии:
1. Спасибо, позвольте мне попытаться адаптировать это к моей конкретной ситуации, и после этого я отмечу ответ.