如何精简Node.js嵌套then/catch代码,减少重复返回逻辑?
优化思路
当前代码存在的重复嵌套then、重复写catch返回逻辑的问题,本质源于两点:
- 没有将内层的Promise沿调用链向上return,导致Promise链无法拍平
- 给每个独立的Promise单独挂载catch,重复处理完全相同的错误返回逻辑
完全可以实现你想要的效果:既不需要多层嵌套then,也仅需写一次{res:false}的错误返回逻辑。
方案1:拍平Promise链 + 统一顶级错误捕获
只要把每一层嵌套的Promise直接return出去,就能把嵌套结构拉成线性的链式结构,最后在整个链的最末端挂载一个catch,所有环节的运行错误都会被这个catch捕获,直接在这里返回{res:false}即可,无需重复书写多遍相同逻辑。
原代码存在一个隐藏bug:当判断users为null要执行remove操作时,没有return这个remove的Promise,会导致外层逻辑等不到remove执行完成就直接走后续流程,返回值不符合预期。
优化后的代码:
const uId = data.uId; const id = data.id; const updates = {}; updates[`/shared/${id}/users/${uId}`] = null; updates[`/users/${uId}/shared/${id}`] = null; const sharedRef = admin.database().ref(`/shared/${id}`); return admin.database().ref().update(updates) .then(() => sharedRef.once("value")) .then((snapshot) => { const users = snapshot.val().users; // 无剩余成员时,直接返回remove的Promise,无需嵌套then if (users == null) { return sharedRef.remove(); } return; }) .then(() => { // 所有流程执行完成,统一返回成功结果 return { res: true }; }) .catch(() => { // 所有环节的错误统一在这里处理,仅写一次 return { res: false }; });
这个结构的特点:
- 所有异步操作线性链式排列,无嵌套then
- 不管是update失败、读节点失败、remove操作失败,都会被最后一个catch捕获,直接返回
{res:false},全程仅需写一次错误返回逻辑 - 执行逻辑和原代码预期完全一致:如果存在剩余成员,读完节点就直接走成功分支;如果没有剩余成员,等remove执行完成再走成功分支
方案2:async/await写法(对新手更友好)
对不熟悉Promise链式写法的开发者来说,async/await的写法更接近同步代码的阅读逻辑,完全没有嵌套结构,同样仅需一个try/catch块就能统一处理所有错误:
async function yourBizLogic(data) { try { const uId = data.uId; const id = data.id; const updates = {}; updates[`/shared/${id}/users/${uId}`] = null; updates[`/users/${uId}/shared/${id}`] = null; const sharedRef = admin.database().ref(`/shared/${id}`); // 第一步:执行节点更新 await admin.database().ref().update(updates); // 第二步:读取共享节点快照 const snapshot = await sharedRef.once("value"); const users = snapshot.val().users; // 第三步:如果共享节点无剩余成员,删除空节点 if (users == null) { await sharedRef.remove(); } // 所有操作执行成功,统一返回 return { res: true }; } catch (err) { // 所有环节的错误统一在这里处理 return { res: false }; } }
这种写法的优势:
- 完全无嵌套结构,代码从上到下阅读即可理解完整执行流程
- 不需要在每一层写catch,只要把所有异步操作放到try块内,任意一步抛出错误都会直接走到catch块,一次返回
{res:false} - 顺带解决了原代码未return内层Promise导致的流程提前结束的bug
内容的提问来源于stack exchange,提问作者aritroper
相关产品推荐
相关产品推荐

