js 线程 之 异步编程(1)

----欢迎查看我的博客----

js 单线程

  相信大家玩 js 很久了,Js语言的执行环境是 “ 单线程 ”。什么是单 线程,就是当一个任务完成之后才会有下一个任务 。 举个栗子,你在奶茶店买奶茶 ,只有一个 奶茶妹妹,客人们都在排队,问你喝什么,你告诉她,她下好单再叫下一个,以此类推,这就是 单线程的同步。再比如到你了,你没选好喝什么,她先问下一位喝什么,等你想好了,再问你喝什么,这就是 单线程的异步。多个奶茶妹妹同事问客人 ,就是多线程。

js 为什么是单线程的。

  为什么 JavaScript 不能有多个 线程 呢?这样能提高效率啊。办事快啊, 我能撩到好几个奶茶妹妹,但这个和 js 的作用有关 ,当初 js 只是为了服务于 游览器 ,用户交互,所以设计了单 线程 , 如果多 线程 你想有多么麻烦,你操作了 dom 是修改 ,同时另外的线程执行了 删除 dom 这时候游览器怎么选择呢?为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主 线程 控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。所以我们任然 坚持说 js 是单 线程 的。

异步同步

  既然 js 是 单线程 的,那么按照我们的之前的栗子, 你去买奶茶,你没想好要喝什么,一直占着位置,估计后面的兄弟们对你肯定不爽了,开始骂娘了 ,所以 这时候我们的 奶茶妹 就很机智,然你在后面等等,先问下一个要喝什么。于是,所有任务可以分成两种。

同步任务(synchronous)

在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

执行过程大概是这样:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)一旦"执行栈"中的当前任务执行完毕,就会执行下一个任务,进入执行栈,开始执行。
(3)主线程不断重复上面的(2)

异步任务(asynchronous)

  不进入主线程、而进入”任务队列”(task queue)的任务,只有”任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
执行过程大概是这样:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。开始执行。
(4)主线程不断重复上面的(3)

浏览器不是单线程的

虽然JS运行在浏览器中,是单线程的,每个window一个JS线程,但浏览器不是单线程的,可能有如下线程:

javascript引擎线程

这个就是我们常说的单线程

界面渲染线程

渲染dom页面的进程

浏览器事件触发线程

有可能触发多个事件。例如 keyup ,clickup 等。

Http请求线程

你可以发起多个请求,至于最多能发送多少请求,我们后面会提到。

如果js是单线程的,那么谁去轮询大的Event loop事件队列?答案是浏览器会有单独的线程去处理这个队列。

js 的 异步编程

  异步编程有这么几种方式:

ES 6以前:

  • 回调函数
  • 事件监听(事件发布/订阅)

ES 6:

  • Generator函数(协程coroutine)
  • Promise对象

ES 7:

  • async和await

* 回调函数

 //一个定时器
 function timer(time, callback){
     setTimeout(function(){
         callback();
     }, time);
 };
  
 timer(3000, function(){
      console.log(123);
 })

   这个最常见,也是我们经常写的。非常简单。一个 setTimeout 然后执行后面的函数。至于 setTimeout 的话 ,我们后面再讲。

* 事件监听(发布/订阅)

  发布—订阅模式可以广泛应用于异步编程中,这是一种替代传递回调函数的方案。比如,我们可以订阅 ajax 请求的 error 、 succ 等事件。 或者如果想在动画的每一帧完成之后做一些事情,那我们可以订阅一个事件,然后在动画的每一帧完成之后发布这个事件。在异步编程中使用发布—订阅模式,我们就无需过多关注对象在异步运行期间的内部状态,而只需要订阅感兴趣的事件发生点。
  这里不详细说了,因为后面我们会把这种设计模式单独拿出来讲。这里举例一个事件监听,其实是一样的:

element.addEventListener("click",function(){
    alert("clicked");
})

* Generator函数

这个函数我用的很少,所以我打算后面专门也来研究一下这个东西。
形式上,Generator 函数是一个普通函数,但是有两个特征。

function关键字与函数名之间有一个星号;

函数体内部使用yield语句,定义不同的内部状态

我们来大概看看这个东西

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}
var hw = helloWorldGenerator();

hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }

Generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,我们可以通过调用 next 方法,使得指针移向下一个状态。

* Promise对象

  这个就比较熟了,之前有提到。不太熟悉的童鞋们可以看这篇文章: 你就需要这篇文章,带你搞懂实战的 Promise 对象 ; 后面我们也会将他拿出来,看看我们的 JavaScript 原生如何实现 promise 对象。

* async和await

  这个也比较熟悉,之前的博客也提到过 ,了解 JavaScript ES7 的 async / await , ; 后面我们也会将他拿出来,看看我们的 JavaScript 原生如何实现 async / await 对象。

结语

  以上就是我们的异步编程方式,我们后面会慢慢将这些东西拿出来讲解 :

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

推荐阅读更多精彩内容