【问题标题】:How to delay get request until async function finishes loading如何延迟获取请求直到异步函数完成加载
【发布时间】:2020-10-03 04:54:44
【问题描述】:

在我的快速服务器中,根 get 请求发生在 async function 完成列出数据库中的文件之前,但 get 请求需要来自函数的信息才能正确呈现页面。如何让get 请求等到其他功能完成?

我看过其他解决方案:

Request - Wait till API call is completed Node.js

How to get Express Node route to wait for function before rendering

Wait a async operation before execute render in express using NodeJs

但对于我的问题,答案似乎不够普遍。

async function listFiles() {

  artWorks = [];

  const [files] = await storage.bucket(bucketName).getFiles();

  files.forEach(file => {
    function splitStr(str) {
      var string = str.split("/");
      artWorks.push(
        {
          imgCategory: string[0],
          subCat: string[1].replace(/-/g, ' '),
          imgSrc: bucket + file.name,
          thumbnail: thumbBucket + file.name.split('.')[0] + "-thumb.jpg",
          alt: string[2]
        });
    }
    var str = file.name;
    splitStr(str);
  });
  console.log("files listed");
}


listFiles().catch(console.error);


app.get("/", function(req, res) {
  let randomArt = Math.floor(Math.random()*artWorks.length);
    setTimeout(() => {
      res.render("index", {
          randomArt: randomArt,
          artWorks: artWorks
        })
    }, 500);
});

您可以看到我当前的解决方案是将res.render 放入setTimeout 中以使其等待,但我设置了任意时间,有时它不起作用。它呈现的页面"index" 使用随机选择的artWorks 数组索引,如果数组索引高于50,则listFiles() 函数尚未完成,它无法加载主页说:

TypeError: Cannot read property 'imgCategory' of undefined

一些注意事项:
listFiles() 函数需要保持独立于 get 请求,因为我在根 get 请求之外的代码的其他部分中调用它。

当有人第一次访问该站点时,它会抛出错误并且不呈现页面,但在刷新时artWorks 数组已经完成并且页面将呈现,我认为是因为它已经缓存了必要的信息。

那么在保持函数独立的同时让渲染等待的最佳方法是什么?

【问题讨论】:

    标签: javascript node.js async-await


    【解决方案1】:

    等待promise通过更改调用后解决:

    listFiles().catch(console.error);
    

    收件人:

    listFiles()
      .then(() => {
        app.get("/", function(req, res) {
          let randomArt = Math.floor(Math.random()*artWorks.length);
          res.render("index", {
            randomArt: randomArt,
            artWorks: artWorks
          })
        });
      })
      .catch(console.error);
    

    【讨论】:

    • 这是一个不错的解决方案,但我确实需要 listFiles() 独立于获取请求。在另一个页面上,用户将从数据库中添加或删除,并针对每种情况调用listFiles()
    • 更新了答案。
    • 好的,我明白了,谢谢。它适用于我的开发环境。将推动生产,如果可行,我将接受您的正确回答。
    • 好的,我认为这是可行的,但是在我清除缓存并尝试访问主页后,它会显示Cannot GET /,但如果我刷新页面,该网站就可以工作。看起来这个解决方案仍然导致页面在 listFiles() 完成填充数组之前呈现,即使使用 .then 任何想法?
    • 您确定在then 中添加app.listen 吗?
    猜你喜欢
    • 2020-10-21
    • 2021-06-06
    • 2017-01-20
    • 2012-07-11
    • 2020-08-20
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 2015-07-10
    相关资源
    最近更新 更多