美文网首页
js 线程 之 异步编程(1)

js 线程 之 异步编程(1)

作者: WEB_Jorie | 来源:发表于2018-07-06 13:53 被阅读0次

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

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

相关文章

  • js 线程 之 异步编程(1)

    ----欢迎查看我的博客---- js 单线程   相信大家玩 js 很久了,Js语言的执行环境是 “ 单线程 ”...

  • JavaScript事件循环

    js是一门单线程的语言,不可能进行多线程编程,异步编程就是多线程编程一种模式,但是我们经常讲到js的异步编程,其实...

  • js中的异步编程

    为什么要异步编程?1、js的单线程2、避免UI渲染和ajax请求造成页面停滞状态3、更好的利用资源 异步编程的主要...

  • js同步异步编程(2)

    js中的同步异步编程 > 浏览器是多线程的,JS是单线程的(浏览器之分配一个线程来执行JS) > 进程大线程小: ...

  • JS执行机制

    首先我们来看几个问题: 1.JS是单线程的么?2.JS有异步么?3.JS单线程怎么实现的的异步 1.JS是单线程的...

  • 11. Promise与异步编程

    1. 异步编程: js是单线程事件循环。单线程就是:函数逐步运行的时候,要从上至下顺序执行。js引擎同一时刻只能执...

  • 读书笔记#Java异步编程实战-上

    Java异步编程实战 chap1 认识异步编程 异步编程概念与作用在使用同步编程方式时,由于每个线程同时只能发起一...

  • ES6 promise理解

    一、promise 是什么 1、Promise 是 JS 中解决异步编程的一种方案。 拓展:js中解决异步编程的...

  • JS异步编程学习笔记

    由于JavaScript是单线程的语言,因此异步编程对于js的重要程度可想而知,可以说没有异步的js程序寸步难行。...

  • 显式使用线程实现异步编程

    显式使用线程实现异步编程 摘要 本章主要讨论如何显式的使用线程实现异步编程,这其中包含如何显式使用线程实现异步编程...

网友评论

      本文标题:js 线程 之 异步编程(1)

      本文链接:https://www.haomeiwen.com/subject/ornvuftx.html