LangChain加载拆分File对象数组遇空结果,异步逻辑求助
问题描述
开发带有文件拖拽区域的JavaScript应用,接收本地拖拽的File对象数组后,使用LangChain加载并拆分文件,编写的函数中中间步骤能正确处理文件,但最终返回的结果为空。代码如下:
import { TextLoader } from 'langchain/document_loaders/fs/text' import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter' import { Document } from 'langchain/document' export async function IngestFiles (files) { if (files.length < 1) return console.log('files', files) const splitter = new RecursiveCharacterTextSplitter( { chunkSize: 100, chunkOverlap: 10 } ) let documents = [] files.forEach(async file => { const loader = new TextLoader(file) const doc = await loader.load() const docOutput = await splitter.splitDocuments([ new Document({ pageContent: doc[0].pageContent }) ]) documents = documents.concat(docOutput) console.log('documents', documents) }) console.log('result', documents) return documents }
问题原因
问题出在forEach循环的异步逻辑上:forEach不会等待内部的异步函数执行完成,当执行到最后的console.log('result', documents)时,所有文件的加载和拆分操作还未完成,因此documents仍为初始的空数组。
解决方案
可以通过两种方式修复该问题:
方式1:使用map + Promise.all
将forEach替换为map,把每个文件的异步处理逻辑包装成Promise,再用Promise.all等待所有Promise完成后合并结果:
import { TextLoader } from 'langchain/document_loaders/fs/text' import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter' import { Document } from 'langchain/document' export async function IngestFiles (files) { if (files.length < 1) return console.log('files', files) const splitter = new RecursiveCharacterTextSplitter( { chunkSize: 100, chunkOverlap: 10 } ) // 生成所有异步任务的Promise数组 const documentPromises = files.map(async file => { const loader = new TextLoader(file) const doc = await loader.load() return splitter.splitDocuments([ new Document({ pageContent: doc[0].pageContent }) ]) }) // 等待所有任务完成,合并多维数组为一维 const documentArrays = await Promise.all(documentPromises) const documents = documentArrays.flat() console.log('result', documents) return documents }
方式2:使用for...of循环
for...of原生支持异步等待,能保证每个文件处理完成后再进行下一个操作,确保结果收集完整:
import { TextLoader } from 'langchain/document_loaders/fs/text' import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter' import { Document } from 'langchain/document' export async function IngestFiles (files) { if (files.length < 1) return console.log('files', files) const splitter = new RecursiveCharacterTextSplitter( { chunkSize: 100, chunkOverlap: 10 } ) let documents = [] // 循环处理每个文件,等待异步操作完成 for (const file of files) { const loader = new TextLoader(file) const doc = await loader.load() const docOutput = await splitter.splitDocuments([ new Document({ pageContent: doc[0].pageContent }) ]) documents = documents.concat(docOutput) } console.log('result', documents) return documents }
两种方式都能确保所有文件的异步处理完成后,再执行结果输出和返回操作,解决最终结果为空的问题。
内容的提问来源于stack exchange,提问作者user1344280
相关产品推荐
相关产品推荐

