javascript - js中函数和变量的访问顺序?

查看:82
本文介绍了javascript - js中函数和变量的访问顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

新学HTML5,遇到个问题,我在利用input type="file"控件读取本地的JSON文件里的JSON数据并插入到body中去,代码如下:

<script>
    var aa = 1;
    var loadFiles = document.getElementById("loadFiles");//获取id为loadFiles的input对象
    function handleFiles(files){
        if(files.length){
            var file = files[0];
            var reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function(){
                aa = 2;
                console.log(aa);
            };
         
            console.log(aa);
        }
    }
</script>
<body>
<input type="file" id='loadFiles' onchange="handleFiles(this.files)" />
<div id="filesContent" ></div>
</body>

我发现两次console.log打印的结果,反而是先aa=1被打印出来,其次onload函数里面的aa=2才被打印出来,我查资料得知reader的onload方法是在它调用readAsText方法后立即调用的,为什么会先打印后面的console(也就是说我在onload方法外面调用的全是aa=1),这个onload函数和后面的console调用顺序究竟是怎样?

解决方案

跟文件大小、读取时间耗时长短无关。
先输出1后输出2是必然的!

证明如下:

首先写一个阻塞函数,用于阻塞JS执行线程一段时间:

function block(delay) {
    var end = +new Date() + delay;
    while(+new Date() <= end){}
}

然后,把它加到你的代码中:

reader.readAsText();
block(5000);
reader.onload = function() {
    console.log(2);
};
block(5000);
console.log(1);

结果是什么?是不论你阻塞多长时间,结果都是先输出1,后输出2。

结论就是:

onload回调函数被设计成了不在当前这一轮事件循环调用

所以,哪怕文件内容瞬间就被读完了,结果也是先输出1。
这不是一个概率性的结论,而是一个确定的结论。

参考:彻底理解同步、异步和事件循环

这篇关于javascript - js中函数和变量的访问顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆