【发布时间】:2019-02-19 23:43:27
【问题描述】:
我正在使用一些新的 JavaScript 功能,例如 async/await 和生成器。我有函数readPages 签名
async function* readPages(....): AsyncIterableIterator<string> {}
我想用一些分隔符连接这个函数的结果。这是我现在的做法
let array = new Array<string>();
for await (const page of readPages(...))
array.push(page);
let result = array.join(pagesDelimiter);
我认为这很冗长。能不能做得更好?
这里是完整的代码供参考
import * as fs from 'fs';
import { PDFJSStatic, PDFDocumentProxy } from 'pdfjs-dist';
const PDFJS: PDFJSStatic = require('pdfjs-dist');
PDFJS.disableWorker = true;
async function* readPages(doc: PDFDocumentProxy, wordsDelimiter = '\t'): AsyncIterableIterator<string> {
for (let i = 1; i <= doc.numPages; i++) {
const page = await doc.getPage(i);
const textContent = await page.getTextContent();
yield textContent.items.map(item => item.str).join(wordsDelimiter);
}
}
async function pdfToText(filename: string, pagesDelimiter = '\n', wordsDelimiter = '\t') {
const data = new Uint8Array(fs.readFileSync(filename));
const doc = await PDFJS.getDocument(data);
const array = new Array<string>();
for await (const page of readPages(doc, wordsDelimiter))
array.push(page);
return array.join(pagesDelimiter);
}
pdfToText('input.pdf').then(console.log);
【问题讨论】:
-
4 行(1 个声明,一个循环,带有数组推送,最后一个用于连接)是......冗长?我看不到代码的重复,我看不到一个臭虫球或一盘装满难以理解的纠缠意大利面。我不明白你到底想“重构”什么?您打算改进什么?
-
类似
readPages(...).join(delimiter):-) -
所以你想要一个更“功能性”的代码而不是一个普通的循环。它让我不由自主地想到 rxjs Observables。您最终可能会得到更多行,但使用的是功能性方法。
-
我只是认为,这是避免 for 循环的好选择。如果写
['a', 'b', 'c'].join('_')比 for 循环更可取,这也应该是(如果存在解决方案)。 RxJS 不能使用 Promises 操作(或者我错了),它是另一个库。我正在寻找原生 JavaScript 解决方案。 -
RxJS 可以使用 promise (
Observable.fromPromise();) ) 运行。它也可以与 Iterable (Observable.from) 一起使用。不过,现在不知道如何混合两者。
标签: typescript async-await async-iterator