Javascript 蓝鸟承诺变量:';未定义不是一个函数';
我有一个nodejs express服务器,我正在与bluebird Promissions合作,以同步所有异步内容 使用AWS RDS MySQL数据库在localhost上一切正常,但当我将服务器上载到我的AWS EC2实例时,我发现此功能存在问题:Javascript 蓝鸟承诺变量:';未定义不是一个函数';,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我有一个nodejs express服务器,我正在与bluebird Promissions合作,以同步所有异步内容 使用AWS RDS MySQL数据库在localhost上一切正常,但当我将服务器上载到我的AWS EC2实例时,我发现此功能存在问题: var Promise = require('bluebird'); var db = require('./db'); exports.matchValue = function (params) { return new
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声明为新的承诺,因为根据if条件,它将接收不同数据库查询函数的值(此函数返回承诺)
当我调用这个函数时,结果是:“未定义的不是函数”
我理解这种行为的发生是因为它首先执行findValue.then()
而不是if/else
块代码,并且由于变量未定义,它可以是一个函数
我认为声明一个变量作为一个新的承诺,它将等待分配给这个变量的函数返回完成,但实际上并没有发生
我做错了什么?有人能帮我吗
谢谢你的建议
我将变量findValue声明为一个新的承诺,因为根据if条件,它将接收不同数据库查询函数的值(此函数返回一个承诺)
在JavaScript中,不能将变量声明为任何类型。这一行:
var findValue = new Promise();
声明变量(var findValue
)并尝试创建承诺(=new promise()
)。Promise
构造函数要求您向其传递一个函数。它尝试将其第一个参数用作函数,由于您没有向其传递任何参数,因此第一个参数的未定义
,因此出现错误
你可以把它改成
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;
}
.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] });
};
exports.matchValue=函数(参数){
var aux=params.find.split('.');
返回(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服务器上返回承诺;尝试记录返回的值/对象以查看它是什么。假设您的db.getValues1
/db.getValues2
函数返回承诺(它们似乎不接受回调,我拒绝假设您在生产中使用同步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;
}
如果可行,那太好了。以下是一些需要考虑的问题:
var findValue=new Promise()
。正如前面所指出的,构造函数需要一个函数作为其参数。我怀疑您解释了实际收到的错误消息。如果是这样,请不要这样做,这会让其他人很难找出错误所在我面临着类似的问题,巧合的是,我也在使用Sequelize 下面是一条重现问题的单行线:
Promise.resolve({ a: 1 }).then(([x]) => {});
输出:
未处理的拒绝类型错误:未定义不是函数
此错误的原因是JavaScript试图对解析的值执行[Symbol.iterator]()
,但由于它是一个对象,因此它没有[Symbol.iterator]
-错误消息中未定义的是值[Symbol.iterator]
更好的错误消息应该是value not iterable
行中的内容
至于为什么会发生这种情况,这一定是Sequelize的一个bug。如果您仍然遇到此问题,请提交一个问题。感谢您的回答T.J.Crowder,但这是我测试的第一件事,也不起作用!它返回相同的结果message@javing:那么你需要澄清这个问题。具体说来,你想说什么从中获取错误?看起来他的db
没有被提示,而findValue
只是变成了undefined
@Bergi:如果findValue
是undefined
,我会预期一个不同的错误(无法读取undefined
的属性'then')).Hi@Bergi和T.J.Crowder,我知道这很老了,但我发现了这里到底发生了什么,我想你们两个可能有兴趣阅读我的答案。我想知道你们中是否有人知道蓝鸟为什么会给出这个疯狂的错误消息。谢谢!你到底从哪里得到错误?什么是params.find
?因为你正在使用params.find.I如果params.find
是一个数组,那么它是相对新的,在旧的JavaScript引擎上不存在。我在上得到了错误。然后(函数(结果)
只有当节点在EC2实例上运行时才会发生这种情况,当节点在本地主机上运行时,结果包含查询响应,params.find只是一个字符串。谢谢。这很奇怪。它表明您从getValues1
(或getValues2
)得到的结果这不是EC2上的承诺。你确定你需要的所有库都正确安装在你的EC2实例上了吗?我已经删除了if/else,并做了与你的回答类似的事情(返回结果)