React应用中Promise未解析致then()提前触发问题排查
修复Promise未正确解析的问题
你的代码核心问题出在else分支的Promise链式调用上,有两个关键错误导致defaultSeason的Promise还没解析就执行了后续的数据库请求:
then()方法参数错误:你直接把database.ref(...).once('value')作为then()的参数传入,这会导致这个数据库请求立即执行,而不是等待defaultSeason解析完成后再执行。then()需要接收一个回调函数,回调函数的参数才是defaultSeason解析后的赛季ID。- 错误使用Promise对象拼接路径:
${defaultSeason}里的defaultSeason是Promise实例,不是解析后的字符串,这会导致数据库路径变成类似[object Promise]的错误格式。
另外,代码里给session添加recordType的逻辑冗余,完全可以在创建session对象时直接添加,不用再遍历一遍找索引。
以下是修复后的完整代码:
const getDefaultSeason = (uid) => { return database.ref(`subs-tracker/users/${uid}/seasons/`) .orderByChild('seasonName').limitToFirst(1).once('value') .then((snapshot) => { let season; snapshot.forEach((childSnapshot) => { season = childSnapshot.key; }) return season; }); }; export const startSetSessions = ( seasonUuid ) => { if ( seasonUuid ) { return ( dispatch, getState ) => { const uid = getState().auth.uid; return database.ref(`subs-tracker/users/${uid}/sessions/${seasonUuid}`) .once('value') .then((snapshot) => { const sessions = []; snapshot.forEach((childSnapshot) => { // 直接在创建时添加recordType,简化逻辑 sessions.push({ id: childSnapshot.key, ...childSnapshot.val(), recordType: 'SESSION' }); }); dispatch(setSessions( sessions )); }); } } else { return ( dispatch, getState ) => { const uid = getState().auth.uid; // 修复Promise链式调用:传入回调函数,用解析后的seasonKey return getDefaultSeason(uid) .then((seasonKey) => { // 这里seasonKey是解析后的赛季ID,正确拼接路径 return database.ref(`subs-tracker/users/${uid}/sessions/${seasonKey}`).once('value'); }) .then((snapshot) => { const sessions = []; snapshot.forEach((childSnapshot) => { sessions.push({ id: childSnapshot.key, ...childSnapshot.val(), recordType: 'SESSION' }); }); dispatch(setSessions( sessions )); }); } } }
关键修改说明:
- 在
else分支中,将defaultSeason.then()的参数改为回调函数,回调函数接收seasonKey(即getDefaultSeason解析后的结果) - 使用
seasonKey拼接数据库路径,确保路径正确 - 简化
recordType的添加逻辑,在创建session对象时直接赋值,避免冗余的遍历和索引查找 - 在
else分支的返回值中,返回整个Promise链,确保Redux能正确跟踪异步操作的完成状态
内容的提问来源于stack exchange,提问作者Luke Marvelly
相关产品推荐
相关产品推荐

