我试图调用两个函数,并将第一个函数的输出作为参数传递给第二个函数。
功能1:
module.exports.getAllStatisticsByUserId = function(id, callback){
User.findById(id, (err, user) =>{
if(err)
throw err;
if(user)
callback(null, user.statistics);
});
}
功能2:
module.exports.getGameByStatisticsId = function(id, callback){
Statistics.findById(id, (err, statistics) =>{
if(err)
throw err;
if(statistics)
callback(null, statistics.game);
});
};
我试图通过将第一个方法的输出作为参数传递来执行第二个方法,但是javascript的异步性质正在弄乱它。我试过实施承诺无济于事。
任何人都可以建议一些好的javascript实践来处理在需要时异步调用函数吗?任何帮助将不胜感激。
答案 0 :(得分:2)
修复the issue I mentioned above后,您可以按顺序调用它们:
module.exports.getAllStatisticsByUserId = function(id, callback){
User.findById(id, (err, user) =>{
if(err) callback(err);
if(user) callback(null, user.statistics);
});
};
module.exports.getGameByStatisticsId = function(id, callback){
Statistics.findById(id, (err, statistics) =>{
if(err) callback(err);
if(statistics) callback(null, statistics.game);
});
};
someService.getAllStatisticsByUserId(id, (err, statistics) => {
if (err || !statistics) {
// handle error
return;
}
someService.getGameByStatisticsId(statistics.id, (err, game) => {
if (err || !game) {
// handle error
return;
}
// handle game
});
});
但是,如上所述in Mongoose documentation:
如果未传递
callback
函数,则返回Query实例,该实例提供特殊的查询构建器界面。 Query具有.then()
函数,因此可以用作承诺。
所以你可以简单地重写这样的调用:
someService.getAllStatisticsByUserId(id).then(statistics =>
someService.getGameByStatisticsId(statistics.id)
).then(game => {
// handle game
}).catch(err => {
// handle error
});
或将其转换为async/await
函数:
async function getGameByUserId(id) {
try {
const statistics = await someService.getAllStatisticsByUserId(id);
const game = await someService.getGameByStatisticsId(statistics.id);
// handle game
} catch (error) {
// handle error
}
}
请注意,async
函数始终返回Promise
,因此您必须await
或将其与.then()
链接以确保查询完成并解决返回的问题价值,如果有的话。
答案 1 :(得分:1)
看起来你应该能写:
getAllStatisticsByUserId("me", (err, stats) => {
getGameByStatisticsId(stats.id, (err, game) => {
console.log(game);
});
});
以下是这些函数返回promises时的样子。
getAllStatisticsByUserId("me")
.then(stats => getGameByStatisticsId(stats.id))
.then(game => console.log(game))
更好的是,如果您能够使用支持async/await
的Node版本,那么您可以编写。
let stats = await getAllStatisticsByUserId("me");
let game = await getGameByStatisticsId(stats.id);
console.log(game);
这意味着稍微重写原始函数(除非User.findById
和Statistics.findById
已经返回promises)。
module.exports.getAllStatisticsByUserId = function(id, callback){
return new Promise((resolve, reject) => {
User.findById(id, (err, user) =>{
if(err) return reject(err);
return resolve(user.statistics);
});
});
}