我很难在JavaScript中使这段代码同步。
评论(1,2和3)表示按顺序发生的事情,现在它可能会在创建新栏之前保存所有者。
我需要findOne,可能是saveBar,然后是saveOwner。
function setMyBar(req, res, next) {
const owner = req.queryOwner;
Bar.findOne({
placeId: req.body.placeId
})
.then((bar) => {
if(bar){
owner.bar = bar; //1
return owner;
}else{
barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude)
.then((savedBar) => {
owner.bar = savedBar; //3
return owner;
})
.catch(e => {return Promise.reject(err) })
}
}).then(() => {
owner.save()
.then(savedOwner => res.json(savedOwner)) //2
.catch(e => next(e));
})
.catch(e => next(e));
}
答案 0 :(得分:2)
您需要在then()
条件的第一个else
中返回承诺。现在没有返回任何内容,所以它会在then
解析之前跳转到下一个barCtrl.saveBar()
尝试
Bar.findOne({
placeId: req.body.placeId
})
.then((bar) => {
if(bar){
owner.bar = bar; //1
return owner;
}else{
// return this promise
return barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude)
.then((savedBar) => {
owner.bar = savedBar; //3
return owner;
})
.catch(e => {return Promise.reject(err) })
}
}).then(() => {
owner.save()
.then(savedOwner => res.json(savedOwner)) //2
.catch(e => next(e));
})
.catch(e => next(e));
答案 1 :(得分:0)
试试这个
function setMyBar(req, res, next) {
const owner = req.queryOwner;
Bar.findOne({
placeId: req.body.placeId
})
.then((bar) => {
if(bar){
owner.bar = bar; //1
return owner;
}else{
// return should do the magic
return barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude)
.then((savedBar) => {
owner.bar = savedBar; //3
return owner;
})
.catch(e => {return Promise.reject(err) })
}
}).then(() => {
owner.save()
.then(savedOwner => res.json(savedOwner)) //2
.catch(e => next(e));
})
.catch(e => next(e));
}
当您在承诺中返回某些内容时,它将作为承诺返回。 并且承诺你当前的承诺必须回报承诺。你不在哪里
答案 2 :(得分:0)
您可以使用承诺链简化很多:
function setMyBar(req, res, next) {
Bar.findOne({
placeId: req.body.placeId
}).then(bar => {
if (bar) {
return bar;
} else {
return barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude);
}
}).then(savedBar => {
const owner = req.queryOwner;
owner.bar = savedBar;
return owner.save();
}).then(savedOwner => {
res.json(savedOwner);
}, e => {
next(e);
});
}
重要的变化:
return
saveBar
承诺,以便等待它,您可以在下一个(外部)then
回调中使用其结果ownwer.bar
作业分配给下一个回调,如果查询已经找到,则只需return bar
,以避免代码重复.catch(e => {return Promise.reject(err) })
答案 3 :(得分:0)
您还可以尝试使用ES7异步函数或async / await语法,这样您就可以编写代码。如果您愿意,还可以异步和并行执行代码。主流浏览器的所有当前版本(IE除外)以及Node.js使用的Google V8引擎都支持它。
我很快就破解了你的代码以使用async / await语法,可能会出现奇怪的错误,因为我只是想向你展示使用异步函数的优点。看起来应该是这样的:
async function setMyBar(req, res, next) {
const owner = req.queryOwner;
try {
let bar = await Bar.findOne({
placeId: req.body.placeId
});
if (bar) {
owner.bar = bar;
} else {
let savedBar = await barCtrl.saveBar(req.body.name, req.body.placeId, req.body.longitude, req.body.latitude);
owner.bar = savedBar;
}
res.json(await owner.save());
} catch (e) {
next(e);
}
}
另请注意,异步函数声明中的async关键字可确保您的函数始终返回promise!
阅读有关功能的一些很棒的链接,还提供了有关承诺的更多背景信息:
https://developers.google.com/web/fundamentals/primers/async-functions
https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8