2017-01-01 66 views
0

我写此代码作为项目的客户 ,当我去表演路线我得到这个500内部服务器错误错误在我的代码的NodeJS

http.get('/files/:id', function(req, res) { 
    var vid; 
    var pap; 
    Videos.find({}, function(err, videos) { 
     if (err) { 
      console.log(err); 
     } else { 
      vid = videos; 
     } 
    }); 

    Papers.find({}, function(err, file) { 
     if (err) { 
      console.log(err); 
     } else { 
      pap = file; 
     } 
    }); 

    Material.findById(req.params.id, function(err, found) { 
     if (err) { 
      console.log(err); 
     } else { 
      res.render('files', { 
       file: pap, 
       video: vid, 
       current: found 
      }); 
     } 
    }); 
}); 

这是我的表演路线代码。

注意:如果我重新加载页面错误消失,页面打开。

+0

自然的错误谁在JS世界潜水。请记住:所有必须等待第三方响应的内容都是异步完成的。它可以是数据库查询请求,一些API请求,一些手表的事件等。(: – num8er

+0

当我改变的变量,从地方到全球 –

+0

对于你的运气,它只是时间里从数据库中的所有答复进来的时候))) – num8er

回答

1

你与猫鼬使用的功能在本质上是异步的;变量vidpap当您运行res.render不被初始化。当您尝试在前端使用这些变量(如翡翠,把手EJS模板,我不知道你使用的是什么),他们是不确定的,并随后导致500错误。您需要运行这些函数,以便运行时所有Mongoose查询的结果可用于res.render;要么使用异步NodeJS库,要么在每个函数内调用另一个函数,然后在最后调用res.render。

解决方法1:使用async Node module

var async = require('async'); 
async.parallel([ 
    // Each function in this array will execute in parallel 
    // The callback function is executed once all functions in the array complete 
    function (cb) { 
     Videos.find({}, function(err, videos) { 
      if (err) { 
       return cb(err); 
      } else { 
       return cb(null, videos); 
      } 
     }); 
    }, 
    function (cb) { 
     Papers.find({}, function(err, papers) { 
      if (err) { 
       return cb(err); 
      } else { 
       return cb(null, papers); 
      } 
     }); 
    }, 
    function (cb) { 
     Material.findById(req.params.id, function(err, found) { 
      if (err) { 
       return cb(err); 
      } else { 
       return cb(null, found); 
      } 
     }); 
    } 
], function (err, results) { 
    if (err) { 
     // If any function returns an error 
     // (first argument), it will be here 
     console.log(err); 
    } 
    else { 
     // Even though the functions complete asynchronously, 
     // the order in which they are declared in the array 
     // will correspond to the position in the array 
     // if it returns anything as a second argument. 
     var videos = results[0]; 
     var files = results[1]; 
     var found = results[2]; 
     res.render('files', { 
      file: files, 
      video: videos, 
      current: found 
     }); 
    } 
}); 

解决方案2:嵌套回调

Videos.find({}, function(err, videos) { 
    var vid = videos; 
    if (err) { 
     console.log(err); 
    } else { 
     Papers.find({}, function(err, file) { 
      var pap = file; 
      if (err) { 
       console.log(err); 
      } else { 
       Material.findById(req.params.id, function(err, found) { 
        if (err) { 
         console.log(err); 
        } else { 
         res.render('files', { 
          file: pap, 
          video: vid, 
          current: found 
         }); 
        } 
       }); 
      } 
     }); 
    } 
}); 
2

的原因是,你需要等待所有的数据库查询到渲染之前完成。在您的代码中,页面可能在其他两个查询完成并返回其数据之前呈现。好消息是Mongoose supports Promises用于异步功能。

http.get('/files/:id', function(req, res) { 
    Promise.all([ 
     Videos.find({}).exec(), 
     Papers.find({}).exec(), 
     Material.findById(req.params.id).exec() 
    ]).then(([video, paper, material]) => { 
     res.render('files', { 
      file: paper, 
      video: video, 
      current: material 
     }); 
    }).catch(error => console.log(error)); 
});