关于正确理解javascript的同步,异步的执行,Event Loop事件循环,异步执行完如何通知主线程的demo


demo下载(需要在本地新建一个json文件模拟ajax请求): http://kallsave.oss-cn-shenzh...


在单线程的javascript编程来说,所有的任务分为两种,一种是同步任务(synchronous),

另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,

才能执行后一个任务,异步任务指的是,不进入主线程,而进入"任务队列"(task queue)的任务,

只有"任务队列"通知主线程,某个异步任务就可以执行了,该任务才会进入主线程执行。

具体来说就是:

1.所有的同步任务都在主线程上执行,形成一个执行栈(execution context stack)

2.主线程之外,还存在一个"任务队列"(task queue),只要异步任务有了运行结果,就在"任务队列"之中放置一个事件

3.一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。

那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行

4.主线程不断重复上面的第三步

只要主线程空了,就会读取"任务队列",这就是javascript的运行机制,这个过程会不断重复

Event Loop 是上面的第三步 这个过程是不断重复的

可以参考:

http://www.ruanyifeng.com/blo...

setTimeout(function(){console.log(1);}, 0);

console.log(2);

上面代码的执行结果总是2,1,因为只有在执行完第二行以后,

系统才会去执行"任务队列"中的回调函数

需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,

主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,

所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。

javascript写手如果称一个函数为"异步的",其意思是这个函数会导致将来再运行另一个函数

后者取自于事件队列(若后面这个函数是作为参数传递给前者的,则成为前者的回调函数)

//理解了异步任务的任务队列(异步)后:

/*var ajaxRequest=new XMLHttpRequest();

ajaxRequest.open("GET","data/activity.json",true)

//ajaxRequest.send(null)

while(ajaxRequest.readyState ===1){ //当有发出open请求 readyState为1

alert(1) //无限弹1,当然永远也轮不懂send运行

} //ajaxRequest.readyState ==4也是不行的

//所以需要引入事件监听脱离同步任务

ajaxRequest.send(null) //异步任务在同步任务全部完成后执行*/

//readyState,onreadystatechange都是要依赖异步的send函数发回来的状态,不过时间很快,

//onreadystatechange对应的函数相当于send的回调函数,要在send执行后才能执行

//(这就是事件监听的用处)

var a=10;

var ajaxRequest=new XMLHttpRequest();

ajaxRequest.open("GET","data/activity.json",true)

ajaxRequest.send(null)

ajaxRequest.onreadystatechange=function(){ //异步事件队列返同步任务对的事件监听

console.log("我是ajax请求回来触发事件监听的标志")

console.log("异步任务ajax请求回来触发事件监听的时刻",new Date().getTime()-c)

}

setTimeout(function(){

console.log("同步任务执行完0.004秒后立刻执行,setTimeout函数实际的延时时间会有偏差")

console.log("异步任务setTimeout执行的时刻",new Date().getTime()-c)

a++

console.log("异步队列返回同步队列,a="+a);

},0)

console.log("同步任务","a="+a)

var four = new Date();

var c = four.getTime()

for(var i=0;i<1000000000;i++){

if(i === 0){

console.log("同步任务,i=0时执行的时刻:",new Date().getTime()-c)

}

if(i === (1000000000-1)){

console.log("同步任务,i=999999时执行的时刻:",new Date().getTime()-c)

console.log("ajax的send()是在我执行完它才开始请求的,并不是我在进行的同时它也在请求,所以send()函数放在脚本的结尾和现在是一样的效果")

}

}

//ajaxRequest.send(null) //实际上send函数是在主线程空了再执行 也就是脚本的结尾



相关阅读:
webpack 怎么引入semantic-ui?
Cordova做的APP里,希望点击按钮时的颜色变化更明显一些,以便更清楚地给用户提示,该怎么弄?
ipad调用UIActivityViewController时系统分享不能完全显示。
GitLab配置CAS认证,前端WEB正常. 但是做git clone等操作时报错如下
django 如何实现文章按时间归档啊
angularjs ng-bind的用法
为什么start = parseInt(spans[this.index].style.top);是undefined?
vue单页面能调到新的页面吗?
HTML 5输入框只能输入汉字、字母、数字、标点符号?正则如何写?
koa+mysql ,插入数据库数据成功,但是无法将数据返回给前台
laravel自带的users表不能被修改吗?
一般在公司开发的话,框架用的多还是原生的PHP+MYSQL用的多呢??
webpack配置react.js问题npm ERR!
如何形象地解释 “结构化数据” 与 “半结构化数据” 的区别
uicollectionviewcell自适应问题
如何看待window.x和var x的区别
如何控制页面所有滚动条随着一个滚动条一起动
Laravel sql 排序
vue.js,我想把自定义组件里面的函数写到methods里面,但不成功
vue activate and deactivate



快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 农产品购销合同样本 计生办干部竞争上岗位演讲 這一刻,讓我給自己說“向來情深,奈何緣淺”! 《定伯斗鬼》读书笔记 企业女职工技能素质及巾帼科技创新调研 心中的新式房屋 忘了我没关系 幸福200字 秋语无声 谒金门(_·上秀邸溪亭) 写赞美母亲的好句子 我的一件小事 柳传志女儿柳青创业史:从高盛最年轻的董事到滴滴总裁 忘却是为了重生 竣工通车庆典欢迎词 小学五年级作文450字:还人类一片蓝天 万人追,不如一人疼;万人宠,不如一人懂。 小学六年级作文550字:公主和王子 1 阳光每天都来 副总经理述职报告 当你在长大面前踟蹰徘徊 自相矛盾 物业公司述职报告 那年的记忆作文1000字 一滴泪 通风现场会发言材料 个人远程教育工作总结 用飞扬的青春抒写人生650字 让自己跑起来作文600字 服装店管理制度 临冬畅想 小学五年级作文550字:(100528周记)即将到来的“六一” 2012年党工委书记述职报告 《心灵的灰烬》教案二(美教版) 在化学教研室教研会上的发言提纲 “三严三实”专题教育研讨交流材料 班主任推荐信样本 幸福深处 所有的一切都静好...... 校长管理心得体会:任校长三年来的体会与感想 2016寒假工代理 快乐是一道难题 两行情诗(诗歌) 回首过去,迎接新年 住在衣服里 电信下半年工作会总结会上的总结讲话 小熊多多买快乐作文500字 故乡的鸟儿 小学四年级作文350字:童年作文 爱情F语

Copyright © 2016 phpStudy |