Cloud Function下载JSON上传Cloud Storage返回200但上传文件为空
问题原因
你的代码核心问题是异步操作没有按顺序等待执行完成:
http.get和后续的response.pipe都是异步IO操作,你触发下载请求后没有等待文件完全写入本地/tmp/post.json,就直接执行了上传逻辑,此时本地文件还处于下载中、甚至是刚创建的空文件状态,所以上传到存储桶的内容为空/大小不对。- 存储桶的
upload方法同样是异步操作,你没有等待上传执行完成就直接返回了200响应,Cloud Function可能在上传流程未结束时就提前回收运行资源,导致上传失败。
修复后的代码
const {Storage} = require('@google-cloud/storage'); const http = require('http'); const fs = require('fs'); const storage = new Storage(); exports.writeToBucket = async (req, res) => { const bucketName = 'tft-test-48c87.appspot.com'; const tmpFilePath = '/tmp/post.json'; try { // 等待文件下载完成 await new Promise((resolve, reject) => { const file = fs.createWriteStream(tmpFilePath); http.get("http://jsonplaceholder.typicode.com/posts?", (response) => { response.pipe(file); // 监听文件写入完成事件 file.on('finish', resolve); // 监听下载、写入错误 file.on('error', reject); }).on('error', reject); }); console.log('文件下载完成'); // 等待文件上传完成 await storage.bucket(bucketName).upload(tmpFilePath, { gzip: true, metadata: { cacheControl: 'no-cache', }, }); console.log('文件上传完成'); res.status(200).send(`${tmpFilePath} 已成功上传到 ${bucketName}`); } catch (err) { console.error('执行出错:', err); res.status(500).send('执行失败:' + err.message); } };
修改说明
- 把异步操作封装为Promise,用
async/await控制执行顺序,确保先完成下载、再执行上传,上传完成后才返回响应 - 增加了全流程的错误捕获,避免异常没有被捕获导致的无响应问题
- 把模块引入、Storage实例初始化移到函数外部,重复利用Cloud Function的运行时上下文,减少冷启动开销
内容的提问来源于stack exchange,提问作者Kel
相关产品推荐
相关产品推荐

