使用Node-JS应用回调设计模式

时间:2016-08-18 14:06:21

标签: javascript node.js callback return-value

我相信我理解基本形式的回调的设计模式。然而,我不知道是否以及如何将这种设计模式应用于这种更复杂的情况。

我正在编写一组用于服务器端的JavaScript函数。如果可能,这些函数必须从外部API返回从本地数据库获取的数据。我想做的是总结:

//dataProvider.js
function DataProvider (dbCredentials, apiCredentials) {
  DB = require('./dbStuff');
  API = require('./apiStuff');
  this.db = new DB(dbCredentials);
  this.api = new API(apiCredentials);
  
  this.getSpecificData = getSpecificDataWrapper(this.db, this.api);
}

function getSpecificDataWrapper(db, api) {
  return function (extraQueryInfo) {
    var result = db.genericGetFunc(specificDBQuery);
    if (!satisfyingResult(result)) {
      result = api.genericGetFunc(specificAPIQuery);
    return result;
  }
}

从主app.js文件调用此函数时,我希望以dataProviderInstance.getSpecificData(extraQueryInfo)执行此操作。现在我为数据库和执行查询的api函数设置了类似的结构。但由于这些查询需要时间,getSpecificData始终返回undefined。

由于代码在不同的文件中,使用这么多回调会让我疯狂。那么如何在这两个或更多级别的深度函数调用中使用回调?

2 个答案:

答案 0 :(得分:1)

我会鼓励你去做承诺而不是回调。 回调的问题在于它最终会变得非常混乱。

对你的问题一个非常好的解决方案就是这样。

AuthName "Développement"
AuthType Basic
AuthUserFile ".htpasswd"
Require valid-user

因此getSpecificData函数将返回一个promise ...你只需要链接然后等待结果

//dataProvider.js
function DataProvider (dbCredentials, apiCredentials) {
  DB = require('./dbStuff');
  API = require('./apiStuff');
  this.db = new DB(dbCredentials);
  this.api = new API(apiCredentials);
  
  this.getSpecificData = getSpecificDataWrapper(this.db, this.api);
}

function getSpecificDataWrapper(db, api) {
  
  return new Promise(function (resolve, reject) {
    
    //I Assume that if this is an async operation, either receives a callback
    //function or returns a promise.
    db.genericGetFunc(specificDBQuery)
      .then (function(result) {
        if (satisfyingResult(result)) resolve(result)
        
        // Again, I Assume that if this is an async operation, either receives a
        //callback function or returns a promise.
        else return api.genericGetFunc(specificAPIQuery);
      })
      .then (function(result){
        resolve(result);
      })
      .catch (function(err){
        reject(err);
      })
    
  });
  
}

希望这有帮助!

答案 1 :(得分:0)

假设您的数据库和API模块也使用回调模式, 那么你应该用a扩展getSpecificData()方法 回调参数。然后调用此回调方法 DB令人满意的结果或API的结果:

function getSpecificDataWrapper(db, api) {
  return function (extraQueryInfo, callback) {
    db.genericGetFunc(specificDBQuery, function(result){
      if(satisfyingResult(result)){
        callback(result);
      }
      else {
        api.genericGetFunc(specificAPIQuery, function(result){
          callback(result);
        });
      }
    });
  }
}

dataProviderInstance.getSpecificData(extraQueryInfo, function(result){
  // handle result here
});