我有一个nodejs express服务器,我正在使用bluebird Promises来同步所有异步内容。
使用AWS RDS MySQL数据库在localhost上一切正常,但当我将服务器上传到我的AWS EC2实例时,我发现此功能有问题:
DataTable dt = new DataTable();
mySqlDataAdapter.Fill(dt);
int socot = dt.Rows.Count;
for (int i = 0; i < socot; i++)
{
String dn = dt.Rows[i][1].ToString();
String gduan = "SELECT tennha FROM duannha WHERE id=@id";
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = gduan;
cmd.Parameters.AddWithValue("@id", dn);
String gtennha = cmd.ExecuteScalar().ToString();
dt.Rows[i][1] = gtennha;
}
我已将变量 findValue 声明为新的Promise,因为根据if条件,它将接收不同数据库查询函数的值(此函数返回Promise)。
当我调用此函数时,结果如下:“undefined is is a function”。
我理解这种行为的发生是因为它首先执行var Promise = require('bluebird');
var db = require('./db');
exports.matchValue = function (params) {
return new Promise(function(resolve, reject) {
var findValue = new Promise();
if (params.find.includes(".")) {
var aux = params.find.split(".");
var matchBy = {};
if (aux[0]) matchBy.a = aux[0];
if (aux[1]) matchBy.b = aux[1];
findValue = db.getValues1(params.limit,params.page,matchBy);
}
else {
findValue = db.getValues2(params.limit,params.page,params.find);
}
findValue
.then(function(result) {
resolve(result);
})
.catch(function(err) {
reject(err);
});
});
}
而不是findValue.then()
块代码,并且因为变量是未定义的,所以它可以是一个函数。
我认为将变量声明为新的Promise,它会等到分配给此变量的函数返回完成,但实际上并没有发生。
我做错了什么?有人能帮我吗?
谢谢你的建议!!
答案 0 :(得分:0)
我已将变量findValue声明为新的Promise,因为根据if条件,它将接收不同数据库查询函数的值(此函数返回Promise)。
在JavaScript中,您不会将变量声明为任何类型。这一行:
var findValue = new Promise();
声明一个变量(var findValue
)并尝试创建一个promise(= new Promise()
)。 Promise
构造函数要求您将其传递给函数。它试图将其第一个参数用作函数,并且由于您没有传递任何参数,因此第一个参数得到undefined
- 因此错误。
您可以将其更改为
var findValue;
...但是您的代码正在成为不必要的承诺创建谬误的牺牲品:只需使用您已有的承诺:
exports.matchValue = function (params) {
var findValue;
if (params.find.includes(".")) {
var aux = params.find.split(".");
var matchBy = {};
if (aux[0]) matchBy.a = aux[0];
if (aux[1]) matchBy.b = aux[1];
findValue = db.getValues1(params.limit,params.page,matchBy);
}
else {
findValue = db.getValues2(params.limit,params.page,params.find);
}
return findValue;
}
答案 1 :(得分:0)
假设您的db.getValues1
/ db.getValues2
函数返回promises(它们似乎没有回调,我拒绝假设您在生产中使用同步DB驱动程序),请尝试以下版本您发布的代码:
var Promise = require('bluebird');
var db = require('./db');
exports.matchValue = function (params) {
var findValue;
if (params.find.includes(".")) {
var aux = params.find.split(".");
var matchBy = {};
if (aux[0]) matchBy.a = aux[0];
if (aux[1]) matchBy.b = aux[1];
findValue = db.getValues1(params.limit,params.page,matchBy);
}
else {
findValue = db.getValues2(params.limit,params.page,params.find);
}
return findValue;
}
如果有效,那很好。以下是一些需要考虑的事项:
您正在创建一个新的Promise。不要那样做。使用Bluebird的promisification例程来宣传标准的,符合节点的函数/库。
Bluebird 2.x和3.x会抛出var findValue = new Promise()
。正如已经指出的那样,构造函数需要一个函数作为其参数。我怀疑你转述了你实际得到的错误信息。如果是这样,不要这样做,这使得其他人很难弄清楚出了什么问题。
下次发布到SO时,请将示例代码缩减为任何人都可以运行的内容并轻松重现您的问题。您可能会在找到最小的复制品的过程中发现您解决自己的问题。如果你不这样做,它将使这里的人们能够更有效地帮助你。
答案 2 :(得分:0)
我遇到了类似的问题,碰巧我也在使用Sequelize。
这里是重现问题的单线:
Promise.resolve({ a: 1 }).then(([x]) => {});
输出:
未处理的拒绝TypeError:未定义不是函数
此错误的原因是JavaScript试图对解析后的值执行[Symbol.iterator]()
,但是由于它是一个对象,因此在其中没有[Symbol.iterator]
-undefined
错误消息是value[Symbol.iterator]
。
更好的错误消息应该是value is not iterable
行中的内容。
关于您为什么会这样,这一定是Sequelize的一个错误。如果您仍然遇到问题,请提出问题。
答案 3 :(得分:-1)
您的.matchValue()
功能应简化为:
exports.matchValue = function(params) {
var aux = params.find.split('.');
return (aux.length < 2) ? db.getValues2(params.limit, params.page, params.find) : db.getValues1(params.limit, params.page, { 'a': aux[0], 'b': aux[1] });
};
有了这个,.then(function(result)
肯定不会因为该线已经消失而被抛出,但函数的调用者可能会抛出。如果是这样,那么您必须(再次)怀疑db.getValues1()
或db.getValues2()
在EC2服务器上没有返回承诺;尝试记录返回的值/对象以查看它是什么。