码迷,mamicode.com
首页 > 编程语言 > 详细

单线程,同步异步,阻塞非阻塞的理解

时间:2017-04-02 13:13:40      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:回调   mmu   lan   tps   set   console   代码   看到了   表示   

一.概念理解

1.同步异步:

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。

2.阻塞非阻塞:

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

作者:严肃
链接:https://www.zhihu.com/question/19732473/answer/20851256
来源:知乎

3.单线程:

我们常说“JavaScript是单线程的”。

所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。不妨叫它主线程。

但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等。这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分。不妨叫它们工作线程。

 

二.JS中的同步异步理解:

1.同步:

Math.sqrt(2);
console.log(‘Hi‘);
第一个函数返回时,就拿到了预期的返回值:2的平方根。
第二个函数返回时,就看到了预期的效果:在控制台打印了一个字符串

2异步:(以异步函数setTimeout为例)

setTimeout(function(){console.log("a")}, 500);
console.log("b");
//"b"
//"a"
setTimeout函数返回时,并不能立即得到结果,而是先运行后面的程序,等到被调用函数通知时(500ms以后通知),再运行。

3.异步过程的构成要素:

  主线程发起一个异步请求,相应的工作线程接收请求并告知主线程已收到(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)。

  所以,从主线程的角度看,一个异步过程包括下面两个要素:

  • 发起函数(或叫注册函数)

  • 回调函数callbackFn 

4.消息队列与事件循环:
工作线程将消息放到消息队列,主线程通过事件循环过程去取消息。消息就是注册异步任务时添加的回调函数。

  • 消息队列:消息队列是一个先进先出的队列,它里面存放着各种消息。

  • 事件循环:事件循环是指主线程重复从消息队列中取消息、执行的过程。

技术分享

作者:manxisuo

链接:https://segmentfault.com/a/1190000004322358

 

三.JS中异步编程的几种方式

1.回调函数:

假设有函数

f1();
f2();
f2必须在f1完成后运行,f1又是一个耗时的应用

 

 则可使用异步调用:


function f1(f2){
    setTimeout(function () {
      console.log("a")
      // f1的任务代码
      f2()}, 1000)}
function f2(){console.log("b")};
f1(f2);
console.log("c");}

//"c"

//"a"

//"b"

这样,就把同步操作变成了异步操作;

 

2.事件监听:采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

 

还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的写法)。
  f1.on(‘done‘, f2);
上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:
  function f1(){
    setTimeout(function () {
      // f1的任务代码
      f1.trigger(‘done‘);
    }, 1000);
  }
f1.trigger(‘done‘)表示,执行完成后,立即触发done事件,从而开始执行f2。

 

3.发布、订阅:

4.Promise对象:

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

 

单线程,同步异步,阻塞非阻塞的理解

标签:回调   mmu   lan   tps   set   console   代码   看到了   表示   

原文地址:http://www.cnblogs.com/YutaoZhou/p/6658769.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!