繁体   English   中英

在 getStaticPaths() 中调用导出时,顶级 function 未运行

[英]Top level function not running when export is called inside getStaticPaths()

我正在从 Next.js SSG(静态站点生成)应用程序访问数据库。 为了防止应用程序每次进行查询时都必须重新连接到数据库,我从一个文件中导出一个全局 promise,然后在一个单独的文件 ( controllers.js ) 中调用它,该文件包含多个直接查询D b。 然后从我的实际组件中的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,
    };
}

我得到的错误是告诉我db是未定义的,因此我不能在它上面使用方法“collection”。 我的结论是,我的匿名异步 function 在getStaticPaths()中调用 getProjects() 时没有运行,因此没有定义db导致错误。 当我在getStaticProps()中调用 getProjects() 时,一切正常,这是怎么回事?

如果db在您调用getProjectsundefined ,则发生以下两种情况之一:

  1. 您只是在await clientPromise解决之前调用getProjects
  2. clientPromise的解析值是undefined

您没有提供足够的信息来调试第二种可能性,所以我们假设第一种是这里的问题。


 (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 function ,它返回一个 promise ,您可以使用该 promise 来确定结果何时可用。

相反,您采取了一种即发即弃的方法,并且依赖于您无法控制时间的副作用。

利用它返回 promise 的事实。

const db = (async function () { 
    const client = await clientPromise;
    const devdb = client.db("dev");
    return devdb;
}();

现在db将是一个 promise ,它立即解析为您想要的值,而不是undefined然后稍后更改。

当然,您需要更改模块的 rest 来解决这个问题。 例如:

 const projects = await db.collection("projects")

会变成

const devdb = await db;
const projects = devdb.collection("projects")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM