未声明async但含Promise的函数能否用await?代码优化方案咨询
解决
await对sqlUpsertRecommendations无效果的问题 问题根源
VSCode提示“'await' has no effect on the type of this expression”,核心原因是sqlUpsertRecommendations函数没有返回内部创建的Promise实例。函数里新建了Promise但没通过return导出,导致函数默认返回undefined,await undefined自然不会产生异步等待的效果。
第一步:修复Promise返回问题
先给函数加上return,让它返回Promise实例:
const sqlUpsertRecommendations = recommendationsArray => { // eslint-disable-next-line no-new return new Promise(resolve => { // 新增return const insertStatus = { .... // 原状态定义 }; // 原函数剩余逻辑... }); };
原代码的其他严重问题(必须修复)
仅返回Promise还不够,原函数的逻辑存在异步管理错误:
- 提前resolve:循环中第一个
txn.executeSql成功就会调用resolve,后续的SQL操作还没执行就直接结束了Promise,导致只有第一条数据被处理。 - 错误处理混乱:错误时仅在最后一条数据处理完才resolve,中间错误无法被捕获;而且错误时用resolve返回错误信息,不符合Promise的规范(应该用
reject传递错误)。
优化后的完整代码
以下是修复了异步管理和错误处理的版本:
const sqlUpsertRecommendations = recommendationsArray => { return new Promise((resolve, reject) => { const insertStatus = { inserted: 0, notInserted: 0, arrayEmpty: true }; // 空数组直接返回 if (recommendationsArray.length === 0) { resolve({ error: false, results: insertStatus, localMessage: 'recommendationsArray.length = 0', }); return; } insertStatus.arrayEmpty = false; // 开启事务 dbConfig.transaction( txn => { // 把每条SQL操作包装成Promise并收集 const sqlTasks = recommendationsArray.map(item => { const { id, recommendation_attribute, recommendation_value, segment_id, target_attribute, target_value, is_deleted, updated_at, name, image, border_color } = item; const params = [ id, recommendation_attribute, recommendation_value, segment_id, target_attribute, target_value, is_deleted, updated_at, name, image, border_color ]; return new Promise((taskResolve, taskReject) => { txn.executeSql( upsertRecommendations, params, () => { insertStatus.inserted += 1; taskResolve(); }, error => { insertStatus.notInserted += 1; crashlytics().recordError(error); __DEV__ && console.log('sqlUpsertRecommendations error:', error); // 这里如果需要某条失败就终止,直接taskReject;如果要继续执行所有任务,就taskResolve taskReject(error); } ); }); }); // 等待所有SQL任务完成:用allSettled会统计所有结果,用all则任意失败就终止 Promise.allSettled(sqlTasks) .then(() => resolve({ error: false, results: insertStatus })) .catch(error => reject({ error: true, message: error.message, results: insertStatus })); }, // 事务本身的错误处理 transactionError => { crashlytics().recordError(transactionError); reject({ error: true, message: transactionError.message, results: insertStatus }); } ); }); };
正确使用await的方式
现在可以配合try/catch正常使用await:
const testFunction = async () => { try { const upsertResult = await sqlUpsertRecommendations(parsedData); console.log('批量插入完成:', upsertResult); // 处理成功逻辑,比如更新UI或上报统计 } catch (err) { console.error('批量插入失败:', err); // 处理错误逻辑,比如提示用户或重试 } };
核心要点总结
- 要让
await生效,异步函数必须返回Promise实例。 - 批量异步操作需统一管理完成时机,避免提前resolve导致逻辑不完整。
- 错误处理遵循Promise规范:用
reject传递错误,配合try/catch捕获异常。
内容的提问来源于stack exchange,提问作者gpbaculio
相关产品推荐
相关产品推荐

