处理异步数据库调用

时间:2018-01-28 21:59:36

标签: javascript node.js asynchronous synchronous alexa

我使用node.js完成了几个项目,并且我意识到异步行为,并且通常应该使用回调函数等。但是困扰我的一件事就是以下内容。

我正在开发Alexa技能,并且我有一个处理用户意图的功能:



'MyFunction': function() {
  var toSay = ""; // Holds info what Alexa says
  
  // Lot of checks and calculations what needs to be said by Alexa (nothing special)
  if(xyz) {
    toSay = "XYZ";
  }else if(abc) {
    toSay = "ABC";
  }else{
    toSay = "Something";
  }
  
  // Here is the "tricky" party
  if(someSpecialEvent) {
    toSay += " "+askDatabaseForInput(); // Add some information from database to string
  }
    
  this.emit(':ask', toSay, this.t('REPROMT_SPEECH')); // Gives the Info to Alexa (code execution stops here)
}




如代码中所述,有一些代码通常用于找出Alexa的输出应该是什么。 只有在罕见的事件中,我才需要查询数据库并将信息添加到String" toSay"。

查询数据库看起来像:



function askDatabaseForInput() { // The function to query the DB
  var params = {
    TableName: "MyTable",
    OtherValues: "..."
  };
  
  // Do the Query
  docClient.query(params, function(err, data) {
    // Of course here are some checks if everything worked, etc.
    var item = data.Items[0]; 
    return item; // Item SHOULD be returned
  });
  
  return infoFromDocClient; // Which is, of course not possible
}




现在我知道,在第一个功能"' MyFunction'"我可以传递变量" toSay"到DB函数然后再到DB Query,如果一切正常,我会做" this.emit()"在DB Query功能中。但对我来说,这看起来非常脏,而且重复性不高。

那么我可以使用" askDatabaseForInput()"返回DB信息并将其添加到String中?这意味着使异步调用同步。

进行同步调用不会影响用户体验,因为代码无论如何都不做其他任何事情而只是创建字符串并且(可能)等待数据库输入。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

所以你可以做两件事:

就像评论的人说你可以使用回调:

function askDatabaseForInput(callback) {
  var params = {
    TableName: "MyTable",
    OtherValues: "..."
  };

  docClient.query(params, function(err, data) {
    if (err) {
      callback(err, null)
    } else {
      var item = data.Items[0]; 
      callback(null, item);
    }
  });
}

或者您可以使用承诺:

function askDatabaseForInput() {
  var params = {
    TableName: "MyTable",
    OtherValues: "..."
  };
  return new Promise(function (resolve, reject) {
    docClient.query(params, function(err, data) {
      if (err) {
        reject(err)
      } else {
        var item = data.Items[0]; 
        resolve(item);
      }
    });
  });
}

然后您可以将函数放在您调用askDatabaseForInput的地方或执行askDatabaseForInput.then(....)

在函数或.then中,您将从数据库中检索到的内容添加到变量toSay

希望这会有所帮助