今天又遇到了上次的問題,上次只是找了個方法解決,沒有搞清楚原理;
router.get('/', function (req, res, next) {
var abc;
Article.findArticle({}, function (err, res) {
if (err) {
console.log(err);
} else {
//操作查詢出的文章
abc = res;
}
});
console.log(abc);//undefined
res.render('blog/blog', {
title:'BLOG',
article:JSON.stringify(abc)
});
});
在express中,查詢數據庫中的數據,后通過回調函數傳遞給全局變量,從而渲染到EJS模板,按以上寫法是無法將res賦值給abc的,或者說,賦值給了abc,但是對abc的操作是在賦值之前的。
一開始我以為是變量的定義問題,后來發現,全都定義為全局變量也不行;
然后我突然發現,這其實是回調函數異步執行的問題;
看以下代碼:
window.onload = function(){
function fn1(callback) {
setTimeout(function(){
console.log(1);
},100);
callback();
};
function fn2() {
console.log(2);
}
fn1(fn2);
fn2();
}
結果是221
console.log(1)
在100毫秒后執行,他后面的代碼都執行完了,他才會執行,在這里,延時100毫秒,就相當于查詢數據庫所需要的時間,數據還未查詢到,abc=res
就無法執行,當這句代碼執行時,后面的操作已經執行完了,但是我們已經看不到了;
因為在整個代碼執行流中,JS的異步機制,決定了他無法等待上一步的執行結果,如果時間稍長(比如需要查詢數據庫),就只能以一個異步的執行流去寫代碼。
要注意摒棄同步的思想。