apollo-server-express多文件上传大文件仅第一个可获取问题咨询
问题原因及解决方法
1. 异步等待写法错误
你当前resolver中的异步等待写法是无效的:Array.map返回的是Promise数组,await仅能处理单个Promise对象,直接await数组不会等待内部所有Promise执行完成,相当于同步返回了未完成的Promise数组。
小文件体积小、处理速度快,在resolver逻辑执行完毕前两个Promise刚好都完成了resolve,所以能正常拿到结果;大文件处理耗时久,第一个Promise完成时第二个还处于pending状态,你直接取结果就会拿到undefined。
正确写法是用Promise.all包裹所有异步任务:
multiUpload: async (obj, { files },{ Models }) => { const results = await Promise.all(files.map(async val=>await val.file)); // 后续业务逻辑 })
2. 上传流并发消费冲突
graphql-upload基于multipart/form-data协议实现文件上传,所有文件的二进制流是按请求中的顺序串行传输的。如果修改Promise.all之后大文件上传仍有问题,说明并发消费多个大文件流时,第一个大文件的流还未完全消费,后续文件的流就因为内部缓冲区溢出被自动销毁了,此时可以改为串行消费所有文件:
multiUpload: async (obj, { files },{ Models }) => { const results = [] for (const val of files) { results.push(await val.file) } // 后续业务逻辑 })
3. 中间件配置问题
请确认graphqlUploadExpress中间件的注册顺序在express.json()、express.urlencoded()等body解析中间件之前,且没有额外使用multer等其他处理multipart/form-data的中间件。
这类中间件会提前消费请求的body流,小文件可以被中间件的缓存完整保存所以不影响,大文件超过中间件默认大小限制时会被截断,导致graphql-upload只能拿到第一个文件的内容。
内容的提问来源于stack exchange,提问作者aykilic
相关产品推荐
相关产品推荐

