在getStaticPaths()内部调用导出时,顶级函数未运行



我正在从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((时,一切都正常,发生了什么?

如果在调用getProjectsdbundefined,则发生以下两件事之一:

  1. 您只是在await clientPromise解析之前调用getProjects
  2. 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")

相关内容

  • 没有找到相关文章

最新更新