2017-01-01 37 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)); 
});