无法读取 node.js 中未定义的属性“then”?
Posted
技术标签:
【中文标题】无法读取 node.js 中未定义的属性“then”?【英文标题】:can not read property 'then' of undefined in node.js? 【发布时间】:2020-04-17 04:50:36 【问题描述】:在 models/index.js 文件中,我正在尝试编写数据库连接
const connectDb = () =>
if (process.env.TEST_DATABASE_URL)
return mongoose.connect(
process.env.TEST_DATABASE_URL,
useNewUrlParser: true ,
);
if (process.env.DATABASE_URL)
return mongoose.connect(
process.env.DATABASE_URL,
useNewUrlParser: true ,
);
;
在主 index.js 文件中,我尝试调用 connectDb()
函数,如下所示:-
connectDb().then(async () =>
if (isTest || isProduction)
// reset database
await Promise.all([
models.User.deleteMany(),
models.Message.deleteMany(),
]);
createUsersWithMessages(new Date());
httpServer.listen( port , () =>
console.log(`Apollo Server on http://localhost:$port/graphql`);
);
);
我收到如下错误:-
TypeError: Cannot read property 'then' of undefined
at Object.<anonymous> (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\src/index.js:95:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module._compile (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\pirates\lib\index.js:83:24)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.newLoader [as .js] (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\pirates\lib\index.js:88:7)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at Object.<anonymous> (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\@babel\node\lib\_babel-node.js:224:23)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)```
【问题讨论】:
你的const connectDb = () =>
不是异步的,也没有返回任何承诺,你必须在 connectDb 函数中解决它,.then
抓住了承诺,因此你得到了错误
@Coderboi,我无法理解,我该怎么做,你能举个例子吗??
您使用的是哪个版本的猫鼬?
@Coderboi 我使用的是猫鼬版本:- "^5.8.3"
检查您的 process.env.TEST_DATABASE_URL 和 process.env.DATABASE_URL
【参考方案1】:
这应该可以工作
const connectDb = async () =>
let x = null;
if (process.env.TEST_DATABASE_URL)
x = await mongoose.connect(
process.env.TEST_DATABASE_URL,
useNewUrlParser: true ,
);
if (process.env.DATABASE_URL)
x = await mongoose.connect(
process.env.DATABASE_URL,
useNewUrlParser: true ,
);
if(x) return Promise.resolve(db) else return Promise.reject("reject");
;
【讨论】:
解决了什么问题?如果mongoose.connect()
返回一个promise(您似乎认为它确实如此,因为您正在使用await
),那么OP 的代码同样可以正常工作,因为OP 已经返回了它。如果 if
语句中的任何一个都没有计算为 true
,那么 OP 的代码和您的代码都会出现问题。
stackblitz.com/edit/js-yxe3f6?embed=1&view=editorconnectDb () 没有异步标签就无法工作,.then(() => ())
需要异步功能,我让他知道发生了什么,所以我没有直接返回 .connect
@jfriend00 你的意见是什么
这只是添加了额外的代码,没有做任何有用的事情。真正的错误是您的if (x)
中没有else
,或者如果在OP 的代码中if
都为false,则没有案例处理。考虑你自己的代码:if (x) return a promise // else return undefined
【参考方案2】:
如果您收到此错误:
TypeError: Cannot read property 'then' of undefined
从这行代码:
connectDb().then(async () =>
那么,这意味着 connectDb()
正在返回 undefined
而不是返回承诺。
查看该代码:
const connectDb = () =>
if (process.env.TEST_DATABASE_URL)
return mongoose.connect(
process.env.TEST_DATABASE_URL,
useNewUrlParser: true ,
);
if (process.env.DATABASE_URL)
return mongoose.connect(
process.env.DATABASE_URL,
useNewUrlParser: true ,
);
;
我们知道,在你所说的 mongoose 版本中,mongoose.connect()
已经返回了一个承诺,所以connectDb()
不能返回一个承诺的唯一方法是,如果你的两个 if
语句都被评估为假,如果两者都没有process.env.TEST_DATABASE_URL
或 process.env.DATABASE_URL
有一个值,或者 mongoose.connect()
实际上没有返回一个承诺(你不知何故安装了旧版本的猫鼬)。
验证环境变量的一种简单方法是添加几个日志语句:
const connectDb = () =>
if (process.env.TEST_DATABASE_URL)
console.log("Found TEST_DATABASE_URL");
return mongoose.connect(
process.env.TEST_DATABASE_URL,
useNewUrlParser: true ,
);
if (process.env.DATABASE_URL)
console.log("Found DATABASE_URL");
return mongoose.connect(
process.env.DATABASE_URL,
useNewUrlParser: true ,
);
console.log("Never supposed to get here")
throw new Error("Need either TEST_DATABASE_URL OR DATABASE_URL set in the environment");
;
仅供参考,您的代码中有很多地方没有进行正确的错误检测或处理,从 db 连接开始,在您的第二个代码块中也是如此。
【讨论】:
以上是关于无法读取 node.js 中未定义的属性“then”?的主要内容,如果未能解决你的问题,请参考以下文章
未捕获的类型错误:无法读取 React ajax 调用中未定义的属性“then”?
如何修复'TypeError:无法读取 Javascript 中未定义的属性'标题'
Ionic5 agm/core:信息窗口 [isOpen] 错误:无法读取 agm-core.js 中未定义的属性“then”
TypeError:无法读取未定义的属性“获取”(Node.js)