我正在使用一些新的JavaScript功能,例如异步/等待和生成器。我有带有签名的功能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);
答案 0 :(得分:1)
好的,我正在处理该代码,我认为目前无法比for-await-of
循环更好地处理此任务。 但是,您可以将该循环隐藏在原型函数的后面...
declare global {
interface AsyncIterableIterator<T> {
toPromise(): Promise<T[]>;
}
}
(async function* (): any {})().constructor.prototype.toPromise = async function<T>(this: AsyncIterableIterator<T>): Promise<T[]> {
let result = new Array<T>();
for await (const item of this)
result.push(item);
return result;
};
所以我的代码
const array = new Array<string>();
for await (const page of readPages(...))
array.push(page);
const result = array.join(pagesDelimiter);
成为
const array = await readPages(...).toPromise();
const result = array.join(pagesDelimiter);
是的,我知道,原型制作是有问题的。但是有趣的是,如何原型化异步迭代器:-)。