蓝鸟承诺变量:'undefined is not a function'
Bluebird promise variable: 'undefined is not a function'
我有一个 nodejs express 服务器,我正在使用 bluebird Promises 来同步所有异步内容。
使用 AWS RDS MySQL 数据库在本地主机上一切正常,但是当我将服务器上传到我的 AWS EC2 实例时,我发现此功能有问题:
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 声明为新的 Promise,因为根据 if 条件,它将接收不同数据库查询函数的值(此函数 return 一个承诺)。
当我调用这个函数时,结果是这样的:"undefined is not a function".
我知道发生这种行为是因为它比 if/else
块代码先 findValue.then()
执行,并且由于变量未定义,它可以是一个函数。
我以为将一个变量声明为一个新的 Promise 它会等到分配给这个变量的函数的 return 完成,但实际上并没有发生。
我做错了什么?有人能帮我吗?
谢谢指教!!
I have declared the variable findValue as a new Promise because depending of the if condition, it will receive the value of a different database query function (this functions return a Promise).
在 JavaScript 中,您没有将变量声明为任何类型。这一行:
var findValue = new Promise();
声明一个变量 (var findValue
) 并尝试创建一个承诺 (= 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;
}
您的 .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()
没有 return EC2 服务器上的承诺;尝试记录 returned value/object 以查看它是什么。
假设您的 db.getValues1
/db.getValues2
函数 return 承诺(它们似乎没有回调,我拒绝假设您在生产中使用同步数据库驱动程序), 请尝试以下版本的 posted 代码:
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 例程 Promisify 标准,符合节点 functions/libraries。
Bluebird 2.x 和 3.x 将抛出 var findValue = new Promise()
。正如已经指出的那样,构造函数需要一个函数作为它的参数。我怀疑您解释了您实际收到的错误消息。如果是这样,请不要那样做,这会让其他人很难找出问题所在。
下次您 post 进行 SO 时,请将您的示例代码缩减为任何人都可以 运行 并随时重现您的问题。您可能会发现在获得最小重现的过程中您解决了自己的问题。如果你不这样做,它会让这里的人更有效地帮助你。
我遇到了类似的问题,巧合的是我也在使用Sequelize。
这里有一个 one-liner 来重现问题:
Promise.resolve({ a: 1 }).then(([x]) => {});
输出:
Unhandled rejection TypeError: undefined is not a function
此错误的原因是 JavaScript 正在尝试对已解析的值执行 [Symbol.iterator]()
,但由于它是一个对象,因此它没有 [Symbol.iterator]
- undefined
在错误信息中是value[Symbol.iterator]
.
更好的错误消息应该是 value is not iterable
.
行中的内容
至于你为什么会这样,那一定是Sequelize的bug。如果您仍然遇到问题,请提出问题。
我有一个 nodejs express 服务器,我正在使用 bluebird Promises 来同步所有异步内容。
使用 AWS RDS MySQL 数据库在本地主机上一切正常,但是当我将服务器上传到我的 AWS EC2 实例时,我发现此功能有问题:
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 声明为新的 Promise,因为根据 if 条件,它将接收不同数据库查询函数的值(此函数 return 一个承诺)。
当我调用这个函数时,结果是这样的:"undefined is not a function".
我知道发生这种行为是因为它比 if/else
块代码先 findValue.then()
执行,并且由于变量未定义,它可以是一个函数。
我以为将一个变量声明为一个新的 Promise 它会等到分配给这个变量的函数的 return 完成,但实际上并没有发生。
我做错了什么?有人能帮我吗?
谢谢指教!!
I have declared the variable findValue as a new Promise because depending of the if condition, it will receive the value of a different database query function (this functions return a Promise).
在 JavaScript 中,您没有将变量声明为任何类型。这一行:
var findValue = new Promise();
声明一个变量 (var findValue
) 并尝试创建一个承诺 (= 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;
}
您的 .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()
没有 return EC2 服务器上的承诺;尝试记录 returned value/object 以查看它是什么。
假设您的 db.getValues1
/db.getValues2
函数 return 承诺(它们似乎没有回调,我拒绝假设您在生产中使用同步数据库驱动程序), 请尝试以下版本的 posted 代码:
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 例程 Promisify 标准,符合节点 functions/libraries。
Bluebird 2.x 和 3.x 将抛出
var findValue = new Promise()
。正如已经指出的那样,构造函数需要一个函数作为它的参数。我怀疑您解释了您实际收到的错误消息。如果是这样,请不要那样做,这会让其他人很难找出问题所在。下次您 post 进行 SO 时,请将您的示例代码缩减为任何人都可以 运行 并随时重现您的问题。您可能会发现在获得最小重现的过程中您解决了自己的问题。如果你不这样做,它会让这里的人更有效地帮助你。
我遇到了类似的问题,巧合的是我也在使用Sequelize。
这里有一个 one-liner 来重现问题:
Promise.resolve({ a: 1 }).then(([x]) => {});
输出:
Unhandled rejection TypeError: undefined is not a function
此错误的原因是 JavaScript 正在尝试对已解析的值执行 [Symbol.iterator]()
,但由于它是一个对象,因此它没有 [Symbol.iterator]
- undefined
在错误信息中是value[Symbol.iterator]
.
更好的错误消息应该是 value is not iterable
.
至于你为什么会这样,那一定是Sequelize的bug。如果您仍然遇到问题,请提出问题。