JAVASCRIPT异步编程 Posted on 2018-08-10 18:04 caryForJava 阅读(189) 评论(0) 编辑 收藏

 

1.前言

平时开发经常会用到js异步编程,由于前端展示页面都是基于网络机顶盒(IPTV的一般性能不太好,OTT较好),目前公司主要采取的异步编程的方式有setTimeout、setInterval、requestAnimationFrame、ajax,为什么会用到异步呢,就拿业务来说,若前端全部采取同步的方式,那加载图片、生成dom、网络数据请求都会大大增加页面渲染时长。

2.JS 运行机制

JS 是单线程运行的,这意味着两段代码不能同时运行,而是必须逐步地运行,所以在同步代码执行过程中,异步代码是不执行的。只有等同步代码执行结束后,异步代码才会被添加到事件队列中。

这里就涉及到执行栈和任务队列:

同步代码是依次存放在执行栈中,遵循LIFO原则;

异步代码存放在任务队列中,任务队列又分宏任务和微任务(微任务执行优先级高于宏任务),遵循FIFO原则;

请看下面代码执行的顺序(可以先思考一下看看与正确输出顺序是否一致)

复制代码
 1 function foo(){  2     console.log('start...');  3     return bar();  4 }  5 function bar(){  6     console.log('bar...');  7 }  8 //这里采用ES6的箭头函数、Promise函数 9 var promise = new Promise(function(resolve,reject){ 10     console.log('promise...'); 11     resolve(); 12 }); 13 promise.then(()=>console.log('promise resolve...')); 14 setTimeout(()=>console.log('timeout...'),0); 15 foo() 16 console.log('end...');
复制代码

 

请看答案


 

 

promise...
start...
bar...
end...
promise resolve...
timeout...

这里分析一下(大家不要纠结任务队列的叫法,本人说明的异步微任务、异步宏任务暂无根据,理解即可,请勿深究):

程序正式开始执行是从9行初始化promise对象开始,首先打印promise...

然后往下执行发现是promise.then回调函数,此为异步微任务,放入任务队列中,等待同步任务执行完才能执行

再往下执行是timeout定时器,此为异步宏任务,也放入任务队列中,等待同步任务执行完、异步微任务才能执行

再往下是foo方法,此为同步任务,借用网络流行的一句话 “JavaScript中的函数是一等公民”,打印日志start...后回调执行bar方法,到这里就有两个执行栈了(依次将foo、bar放入栈中,bar执行完就弹出栈,foo依次弹出)

关于并发模型和Event Loop 请看MDN(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop)

3.异步编程

关于异步编程的方式,常用的定时器、ajax、Promise、Generator、async/await,详细介绍如下:

3.1.定时器

3.1.1.setTimeout与setInterval

这里拿setTimeout来举例

简单的时钟

复制代码
 1 (function(){  2             var div = document.createElement('div'),timer;  3             document.body.appendChild(div);  4             //同步代码,5s后执行异步代码块显示时钟 5             //doSomething() 6             setTimeout(function(){ 
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信