[英]Best practices in context of asynchronous Javascript when calling functions in functions?
我試圖調用兩個函數,並將第一個函數的輸出作為參數傳遞給第二個函數。
功能一:
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實踐,以在彼此需要時異步處理調用函數? 任何幫助,將不勝感激。
解決了我上面提到的問題之后,您可以像這樣依次調用它們:
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
});
});
但是,正如貓鼬文檔中所述 :
當未傳遞
callback
函數時,將返回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()
以確保查詢完成並解析返回的值(如果有)。
看來您應該能夠寫:
getAllStatisticsByUserId("me", (err, stats) => {
getGameByStatisticsId(stats.id, (err, game) => {
console.log(game);
});
});
如果這些函數改為返回promise,將顯示以下內容。
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
已經返回諾言)。
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);
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.