JavaScript多.then调用执行顺序修正求助:实现指定同步流程
解决JavaScript Promise执行顺序问题
你的问题核心是Promise链没有正确串联,当需要创建新Bar的时候,内部的saveBar Promise没有返回给外层的then链,导致外层的owner.save()(注释2)会在saveBar完成前就执行,打乱了预期的顺序。下面给你两种解决方案:
方案一:修复原Promise链
只需要在else块里return barCtrl.saveBar()的Promise链,让外层的then等待这个异步操作完成后再执行后续逻辑。修改后的代码如下:
function setMyBar(req, res, next) { const owner = req.queryOwner; Bar.findOne({ placeId: req.body.placeId }) .then((bar) => { if(bar){ owner.bar = bar; return owner; }else{ // 关键:返回内部Promise链,让外层then等待它完成 return barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude) .then((savedBar) => { owner.bar = savedBar; return owner; }) .catch(e => Promise.reject(e)); } }).then((updatedOwner) => { // 这里拿到的是已赋值bar的owner(不管是查询到的还是新建的) return updatedOwner.save() .then(savedOwner => res.json(savedOwner)) .catch(e => next(e)); }) .catch(e => next(e)); }
原来的else块没有返回内部Promise,导致外层第一个then会立即返回undefined,第二个then直接执行owner.save()——此时owner.bar可能还没被新创建的bar赋值。现在return之后,外层then会等待saveBar完成,拿到赋值后的owner再执行保存操作。
方案二:用async/await简化逻辑(更推荐)
async/await能让异步代码看起来像同步代码,顺序更清晰,也不容易出错。把函数改成async函数,用await处理所有异步操作:
async function setMyBar(req, res, next) { try { const owner = req.queryOwner; // 1. 先执行findOne,等待查询完成 const bar = await Bar.findOne({ placeId: req.body.placeId }); if (!bar) { // 2. 若需创建,执行saveBar并等待完成 const savedBar = await barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude); owner.bar = savedBar; } else { owner.bar = bar; } // 3. 最后执行saveOwner,等待保存完成 const savedOwner = await owner.save(); res.json(savedOwner); } catch (e) { next(e); } }
这里的执行顺序完全符合你的预期:所有异步操作都会按顺序等待,逻辑一目了然,还避免了Promise嵌套的回调地狱。
内容的提问来源于stack exchange,提问作者Matheus Maia
相关产品推荐
相关产品推荐

