Firebase Function未等待GCS回调执行完就提前返回如何解决?
问题根源
pathList分支采用回调方式调用getFiles,该异步逻辑未被async/await体系捕获,函数执行到return语句时回调还未执行完成,list尚未被赋值,因此返回null。
解决方法
将回调形式的分页查询逻辑封装为Promise,通过await等待Promise执行完成后再返回结果即可。
修改后完整代码
import * as functions from 'firebase-functions'; import { Storage } from '@google-cloud/storage'; import { globVars } from '../admin/admin'; const projectId = process.env.GCLOUD_PROJECT; // 全局公共变量配置 const { keyFilename } = globVars; // 存储实例初始化 const storage = new Storage({ projectId, keyFilename, }); export const gcsListPath = functions .region('europe-west2') .runWith({ timeoutSeconds: 540, memory: '256MB' }) .https.onCall(async (data, context) => { if (context.auth?.token.email_verified) { const { bucketName, prefix, pathList = false, fileList = false } = data; let list; const options = { autoPaginate: false, delimiter: '', prefix, }; if (pathList) { options.delimiter = '/'; // 回调逻辑封装为Promise list = await new Promise((resolve, reject) => { const test: any[] = []; const callback = (err: any, _files: any, nextQuery: any, apiResponse: any) => { // 新增错误处理 if (err) return reject(err); test.push(...apiResponse.prefixes); console.log('test : ', test); console.log('nextQuery : ', nextQuery); if (nextQuery) { storage.bucket(bucketName).getFiles(nextQuery, callback); } else { // 所有分页加载完成后返回结果 resolve(test); } } storage.bucket(bucketName).getFiles(options, callback); }) } if (fileList) { const [files] = await storage .bucket(bucketName) .getFiles(options); list = files.map((file) => file.name); } return { list }; } else { return { error: { message: 'Bad Request', status: 'INVALID_ARGUMENT' }, }; } });
修改说明
- 用Promise包裹原有回调逻辑,异步执行完成时调用resolve返回结果,出错时调用reject抛出错误
- pathList分支新增await等待Promise执行完成,直接将返回的前缀数组赋值给list
- 补充了回调内的错误捕获逻辑,避免运行时报错无感知
内容的提问来源于stack exchange,提问作者Trevor Lazarus
相关产品推荐
相关产品推荐

