处理异步数据库调用
Handle async DB calls
我用 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 的输出应该是什么。
只有在罕见事件 "someSpecialEvent" 上,我才需要查询数据库并将信息添加到字符串 "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" 传递给数据库函数,然后传递给数据库查询,如果一切正常,我会在数据库查询函数中执行 "this.emit()"。但是对我来说,这看起来很脏而且不能再使用。
那么有没有一种方法可以使用 "askDatabaseForInput()" 到 return 数据库信息并将其添加到字符串中?这意味着使异步调用同步。
进行同步调用不会影响用户体验,因为代码并没有做任何其他事情,它只是创建字符串并且(可能)正在等待数据库输入。
感谢您的帮助。
所以你可以做两件事:
就像评论的人说你可以使用回调:
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
希望对您有所帮助
我用 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 的输出应该是什么。 只有在罕见事件 "someSpecialEvent" 上,我才需要查询数据库并将信息添加到字符串 "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" 传递给数据库函数,然后传递给数据库查询,如果一切正常,我会在数据库查询函数中执行 "this.emit()"。但是对我来说,这看起来很脏而且不能再使用。
那么有没有一种方法可以使用 "askDatabaseForInput()" 到 return 数据库信息并将其添加到字符串中?这意味着使异步调用同步。
进行同步调用不会影响用户体验,因为代码并没有做任何其他事情,它只是创建字符串并且(可能)正在等待数据库输入。
感谢您的帮助。
所以你可以做两件事:
就像评论的人说你可以使用回调:
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
希望对您有所帮助