我正在从Next.js SSG(静态站点生成(应用程序访问数据库。为了防止每次我进行查询时应用程序都必须重新连接到数据库,我从一个文件导出一个全局promise,然后在一个单独的文件(controllers.js
(中调用它,该文件包含多个直接查询数据库的函数。然后从我实际组件中的getStaticProps()
和getStaticPaths()
方法中调用这些函数。这是controllers.js
:的代码
import clientPromise from "./clientPromise";
let client;
let db;
(async function () {
// Await cannot be used outside of an async function (on the top level/module).
// So we must call it below inside this async function that we immediately call instead of above where it is initialized.
client = await clientPromise;
db = client.db("dev"); // use development database
})();
// Query "technologies" collection:
export async function getTechnologies() {
const technologies = await db
.collection("technologies")
.find({})
.toArray();
return JSON.parse(JSON.stringify(technologies));
}
// Query "projects" collection:
export async function getProjects() {
const projects = await db
.collection("projects")
.find({})
.toArray();
return JSON.parse(JSON.stringify(projects));
}
下面是我调用控制器的一个片段:
// This works perfectly:
export async function getStaticProps() {
const projects = await getProjects();
return {
props: { projects: projects },
}
};
// This causes the error:
export async function getStaticPaths() {
const projects = await getProjects();
return {
paths: [{ params: {_id: "placeholder"} }],
fallback: false,
};
}
我得到的错误告诉我CCD_ 5是未定义的,因此我不能使用方法";集合";我得出的结论是,当在getStaticPaths()
中调用getProjects((时,我的匿名异步函数本应立即调用自己,但它没有运行,因此db
没有被定义,导致了错误当我在getStaticProps()
内部调用getProjects((时,一切都正常,发生了什么?
如果在调用getProjects
时db
是undefined
,则发生以下两件事之一:
- 您只是在
await clientPromise
解析之前调用getProjects
- CCD_ 14的解析值为CCD_
您没有提供足够的信息来调试第二种可能性,所以让我们假设第一种是这里的问题。
(async function () { // Await cannot be used outside of an async function (on the top level/module). // So we must call it below inside this async function that we immediately call instead of above where it is initialized. client = await clientPromise; db = client.db("dev"); // use development database })();
这里有一个async
函数,它返回一个promise,您可以使用该promise来确定结果何时可用。
相反,你采取了即发即弃的方法,并且依赖于一种你无法控制的副作用。
利用它回报承诺的事实。
const db = (async function () {
const client = await clientPromise;
const devdb = client.db("dev");
return devdb;
}();
现在db
将是一个承诺,它将立即解析为您想要的值,而不是undefined
,然后再更改。
当然,您需要更改模块的其余部分才能考虑到这一点。例如:
const projects = await db .collection("projects")
将成为
const devdb = await db;
const projects = devdb.collection("projects")