摒弃同步
JS回调函数中无法改变外部变量的问题 - CSDN博客 https://blog.csdn.net/qq_23870025/article/details/77920898
今天又遇到了上次的问题,上次只是找了个方法解决,没有搞清楚原理;
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的异步机制,决定了他无法等待上一步的执行结果,如果时间稍长(比如需要查询数据库),就只能以一个异步的执行流去写代码。
要注意摒弃同步的思想。