【问题标题】:express render called before parameter evaluate在参数评估之前调用快速渲染
【发布时间】:2017-06-23 08:02:24
【问题描述】:

我对 nodejs、express 和 javascript 还是很陌生。 我有一个代码:

router.get('/', function(req, res, next) {
    const content = fileReader();

    res.render('index', { "content" :  content } );
});

fileReader 正在使用 fs.readFileSync 在 for 循环中读取文件,因此它首先读取所有文件,然后返回一个大字符串。

这个字符串然后被传递给视图并渲染。

上面的代码工作正常,但是当我把它改成这样时:

router.get('/', function(req, res, next) {
    res.render('index', { "content" :  fileReader() } );
});

它不起作用。页面已渲染,但内容为空。

fileReader 函数:

const fileReader = function()
{
    let low = 0;
    let high = 9;

    let content = "";

    for( ; low <= high; low++ )
    {
        if( fs.existsSync( contentDir + "/" + low ) )
        {
            content += fs.readFileSync( contentDir + "/" + low, "utf-8" );
        }
        else
        {
            break;
        }
    }

    return content;
}

有人能解释一下这里发生了什么吗?为什么在 fileReader() 完成之前调用渲染?不应该先执行函数并调用渲染等待结果吗?或者render和fileReader是并行调用的?

请解释一下。

【问题讨论】:

  • 你能发布 fileReader() 的代码吗?
  • 两个例子是相等的。你确定第一个会产生真正的结果吗?
  • @roughcoder 添加了文件读取器
  • @Jonasw 它当前读取了 3 个包含内容的文件并正确发送,我可以在浏览器中看到内容,但是使用第二个 sn-p 我不能
  • 两者相等。错误在其他地方,查看控制台...

标签: javascript node.js express asynchronous


【解决方案1】:

在 nodeJs 中使用同步功能不是一个好主意,我很确定这就是它在没有内容的情况下呈现您的页面的原因。

你应该做的是:

const fileReader = function()
{
   return new Promise((resolve,reject)=>{
     let low = 0;
     let high = 9;

     let content = "";

     for( ; low <= high; low++ )
     {
       fs.readFile( contentDir + "/" + low, "utf-8",(err,data)=>{
           if(err){
               reject(err);
           }
           content += data;
       });
     }
     resolve(content)
   });

}

为您的文件阅读器和以下为您的路线:

router.get('/', function(req, res, next) {
    fileReader().then((data)=>{
        res.render('index', { "content" :  data } );
     }).catch((error)=>{
          //handle your error
     }); 
 });

【讨论】:

  • 如果 fs.readFile 是异步的,那么在填充内容之前不会调用解析?还是先执行并完成resolve之前的代码?或承诺返回对内容的引用,因为你这样做了。然后用空内容调用解析,但在读取文件时填充内容?这是否也保证了将文件添加到内容中的顺序?还是会(可能)是随机的?感谢您的回答,但请您详细说明一下
  • 抱歉这个迟到的答案,我一直在寻找更好的解决方案,结果发现了这个:blog.risingstack.com/node-hero-async-programming-in-node-js 如果您继续滚动到“承诺”一章,您可以找到解决问题的方法。这个过程很简单,他用一个 promise 包装 fs.stat 函数,然后用Promise.all() 解决它们。你可以用fs.readFile()而不是fs.stat()做同样的事情
  • 谢谢,我玩得更多了,实际上也想出了这个,但我不会拒绝没有文件的承诺,但总是解决,区别在于价值。如果我正确理解第一个拒绝,停止处理其余的承诺,所以如果第一个文件不存在,我将永远不会阅读其余的。所以我有一个承诺数组并等待所有承诺,即使出现 NaN 值的错误也可以解决,然后过滤结果数组并仅使用来自 fs 读取的数据,然后将其作为新数组发送以查看,这种方式也是订单有保证。
猜你喜欢
  • 2019-12-22
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2014-12-08
相关资源
最近更新 更多