初步浅析浏览器异步机制

先说一下JavaScript异步的概念:
首先因为js是单线程的语言,且没有异步的特性。

然后js的宿主环境是在浏览器端,js的异步操作是浏览器来提供的,浏览器的js引擎在执行js代码的时候也只是会提供一条线程去执行,真抠...并且!js(主栈列内的js,后文解析什么是主栈列)代码执行会阻塞渲染线程和浏览器事件触发线程,后面这两个线程是属于浏览器内的常驻线程,当然还有其他的比如说http请求线程,那么比如说我们js代码内有一个是改变某个DOM元素样式的代码,执行了之后只是记录下这个渲染事件,不会去切换渲染线程进行渲染,而是继续执行剩下的主栈列内的代码,好烦..发现又要解析主栈列和任务队列的概念..可以去看阮一峰的event loop解析,就是说,算了上代码吧:

$.ajax({   
type:'get',   
url:url,  
beforeSend:function() {
      console.log('发送请求了,别看我在ajax内,其实跟它没什么关系')         
   },  
success:function(data){      
      console.log('ajax执行完毕,我比setTimeout的事件优先级要高')            
   },  
})
setTimeout(function() {   
console.log('定时器也完了')
},0)
console.log('我在主栈列,让我先走')
//触发顺序
1.发送请求了,别看我在ajax内,其实跟它没什么关系
2.我在主栈列,让我先走
3.jquery-1.9.1.min.js:5 XHR finished loading: GET "http://localhost:2000/123".
4.ajax执行完毕
5.定时器也完了

js引擎在解析js代码的时候,遇到settimeout和setInterval或者ajax都会先告诉它们缓缓,你们先进任务队列里面等等,我执行完剩下在主栈列内的代码先。

然后执行完主栈列的代码之后,js线程完事之后,并不会马上去任务队列内找任务放到主栈列,而是..先查找刚刚是不是有需要渲染引擎要干的是..比如说你要改某个DOM元素的背景色,如果有的话,那么就会切换渲染线程,先把页面的渲染需要的repaint和reflow做了,关于repaint和reflow在这里不做陈述,有兴趣google一下吧。

那让渲染引擎做完了渲染工作,浏览器才回去查找任务队列有没有人挂号,采取的是轮询机制,跟医生看病人差不多,就是说一个一个来,随便说一句ajax比settimeout和setInterval优先级要高的,比如说执行完ajax事件1,就回去看任务队列?nonono,先看有没有渲染引擎要做的事,就是说再走一次刚刚主栈列的流程,没有渲染的事了?那就下一位病人吧。

回到主题...为什么我们需要异步,因为刚刚前文所说的js阻塞,如果说ajax是同步执行的..那么就会等服务器响应我的请求,拿到数据再做其他事情,那如果服务器不行请求很久那岂不是很low,那么浏览器干了什么就是在走到ajax的时候,在把它推到任务队列之前,起一个http线程,去发送请求,请求完成了,再讲ajax事件推到任务队列的末端,从而实现异步,在说一句就是根据上面所说的其实settimeout和setInterval要比预期的事件要多一点的,因为在队列中,不是即刻执行,明天再更新。

好吧,干货来了,在日常的写(lu)作(ma)中我们应该怎么样优(zuo)雅(si)地利用异步机制去完成我们想要的异步操作呢:

(一)welcome to callback hell(回调函数)

function getSomething(fn){
   var num=0;
   settimeout(function(){
       num=1;
       fn(num);
   })
}
function compute(x) {
   alert(x * 2);
}
getSomething(compute);//任性,不喜欢大小写命名法

如上文所说,settimeout内的js代码都进入了主栈列,那么执行顺序就是从上至下了,但是在复杂的需求下这种方法会产生callback hell,并且还不容易看出详细异步步骤,不简单的逻辑的话可以用用。

(二)promise

function getSomething() { 
    var r = 0; 
    return new Promise(function(resolve) { 
        setTimeout(function() { 
            r = 2; 
            resolve(r); 
        }, 10); 
    });}
function compute(x) { 
    alert(x * 2);
}
getSomething().then(compute);
//没有接触Promise的朋友可以去看看Promise的使用,因为一时半会又讲不完...本文仅提供异步方法

(三)generator

function getSomething() {   
    var r = 0;   
    setTimeout(function() {      
        r = 2;      
        it.next(r);   
    }, 10);
}
function *compute(it) {   
    var x = yield getSomething();   
    alert(x * 2);
}
var it = compute();
it.next();
//我只负责提供demo......详细可以去看es6的教程

(四)promise + generator

function getSomething() {   
    var r = 0;   
    return new Promise(function(resolve) {      
    setTimeout(function() {         
        r = 2;         
        resolve(r);      
    }, 10);   
 });
}
function *compute() {   
    var x = yield getSomething();   
    alert(x * 2);
}
var it = compute();it.next().value.then(function(value) {   
    it.next(value);
});

(五)async (ES6都玩腻了,ES7还远吗,异步操作终极大法)

function getSomething() { 
    var r = 0; 
    return new Promise(function(resolve) { 
        setTimeout(function() { 
        r = 2; 
        resolve(r); 
    }, 10); 
});}
async function compute() { 
    var x = await getSomething(); 
    alert(x * 2);
}
compute();

困死本宝宝了..1点了。

好咯,晚安,world peace.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,426评论 25 707
  • 刚开始使用JS异步的时候,有这样的疑问:JS不是单线程的吗?为什么会有异步机制?但是如果没有异步机制,定时器又是怎...
    盛夏晚清风阅读 1,623评论 0 11
  • 五月,美好的时光 你的眼睛犹如朝阳 清澈透明而有温度 你的微笑犹如晨风 穿越岁月依然纯真美好 你的双手能撑得起屋顶...
    网络上的风阅读 291评论 0 1
  • 有这样的几个阶段。 初高中甚至大学的时候我都爱写那些矫揉造作的东西,那些把各色形容词名词拼命堆砌在一起,看起来就像...
    陈蹦迪阅读 338评论 0 3
  • Mybatis 简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBa...
    sT丶阅读 543评论 0 0