Typescript 如何重构简单的等待循环?

Typescript 如何重构简单的等待循环?,typescript,async-await,async-iterator,Typescript,Async Await,Async Iterator,我正在使用一些新的JavaScript特性,比如async/await和Generator。我有带签名的函数readPages async function* readPages(....): AsyncIterableIterator<string> {} async function*readPages(..):AsyncIterableIterator{} 我想用一些分隔符来表示这个函数的结果。我现在是这样做的 let array = new Array<string

我正在使用一些新的JavaScript特性,比如async/await和Generator。我有带签名的函数
readPages

async function* readPages(....): AsyncIterableIterator<string> {}
async function*readPages(..):AsyncIterableIterator{}
我想用一些分隔符来表示这个函数的结果。我现在是这样做的

let array = new Array<string>();

for await (const page of readPages(...))
    array.push(page);

let result = array.join(pagesDelimiter);
let array=new array();
用于等待(常数页,共readPages(…)
array.push(第页);
让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);
import*作为来自“fs”的fs;
从“pdfjs dist”导入{PDFJSStatic,PDFDocumentProxy};
const PDFJS:PDFJSStatic=require('PDFJS-dist');
PDFJS.disableWorker=true;
异步函数*readPages(doc:PDFDocumentProxy,wordsDelimiter='\t'):AsyncIterableIterator{
for(设i=1;i item.str)。join(wordsDelimiter);
}
}
异步函数pdfToText(文件名:string,pagesDelimiter='\n',wordsDelimiter='\t'){
const data=newuint8array(fs.readFileSync(filename));
const doc=wait PDFJS.getDocument(数据);
常量数组=新数组();
用于等待(阅读页面的常量页面(文档、文字限制))
array.push(第页);
返回数组.join(pagesDelimiter);
}
pdfToText('input.pdf')。然后(console.log);

好的,我正在更多地使用该代码,我认为目前不可能比使用
更好地处理该任务,以等待循环但是,您可以将该循环隐藏在原型函数后面

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;
};

是的,我知道,原型设计是有问题的。但有趣的是,如何原型化异步迭代器:-)。

4行(1个声明,一个循环,带有数组推送,最后一行用于连接)是。。。冗长的?我看不到代码的重复,我看不到一团泥巴或一盘难以理解的意大利面条。我不明白你到底想“重构”什么?您打算改进什么?类似于
readPages(…).join(delimiter)
:-)这样您就需要一个更“实用”的代码,而不是普通的循环。它让我自然而然地想到了rxjs的可观测性。您可能会得到更多的行,但使用函数方法。我只是认为,这是避免for循环的一个很好的候选者。如果写入
['a'、'b'、'c'].join('u')
比for循环更可取,这也应该是(如果存在解决方案)。RxJS不能在承诺的情况下运行(也许我错了),这是另一个lib。我正在寻找本机JavaScript解决方案。RxJS可以使用promise(
Observable.fromPromise()
;)进行操作。它也可以使用Iterable(可观察的。从)。不过,现在还不知道如何将两者混合。
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);