You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:07:16