簡體   English   中英

在函數中調用函數時在異步Javascript上下文中的最佳做法?

[英]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.findByIdStatistics.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM