一、什么是”异步非堵塞式”?

这个名字听起来非常恶心难懂,但假设以 买内裤 这件事情来比喻运行程序的话就非常easy理解“异步非堵塞式”的涵义了。

比如你是一个CPU的线程。你须要去运行一段 买内裤的程序, 你所需运行的步骤大致例如以下,

  1. 到一个商店里问老板, 你们店里还有没有nb牌内裤?
  2. 买到内裤。穿上
  3. 去小卖店买点火腿回家喂狗

这时候。你作为一个线程,你可能会遇到几种状况或选择。

  1. 店里面没货了。老板一直不答应你(堵塞你),你也一直等着(同步),第三天有货了才告诉你有了。你赶紧拿到穿上。再去买火腿 – [同步堵塞模式]
  2. 老板立即告诉你“没货了”(不堵塞你),然后你每天去店里问一声,直到有货了赶紧穿上,再去买东西喂狗 – [同步非堵塞]
  3. 你让老板有货了打电话叫你过来取。老板说“好的”(非堵塞),然后你就先去买东西喂狗了,过了两天老板叫你过去,你才拿到内裤并穿上 – [异步非堵塞]
  4. 你让老板有货了打电话叫你过来取, 老板又没答应你(堵塞), 然后你本来打算去先去买火腿的(异步),这时候也没法去了。

     – [异步堵塞]

非常明显。第三种方法是最聪明,前两种方法都略显效率低下。所以依据我们的理解,

同步或非同步,表明着是否须要将整个流程顺序地完毕

堵塞或非堵塞。意味着你调用的函数会不会立马告诉你结果

二、在js中的堵塞与同异步

你有一个函数和一段程序。

2.1 js中的同步堵塞

// 这是一个堵塞式函数, 将一个文件拷贝到还有一个文件上
function copyBigFile(afile, bfile){
var result = copyFileSync(afile,bfile);
return result;
}

调用这个”copyBigFile()”函数。将一个大文件拷贝到还有一个文件上。将耗时1小时。意味着这个函数的将在一个小时之后返回。

//这是一段程序
console.log("start copying ... ");
var a = copyBigFile('A.txt', 'B.txt'); //这行程序将耗时1小时
console.log("Finished"); // 这行程序将在一小时后运行
console.log("处理一下别的事情");  // 这行程序将在一小时后运行
console.log("Hello World, 整个程序已载入完毕,请享用"); // 这行程序将在一小时后运行

以上的程序就是一个同步堵塞的样例。由于copyFileSync函数返回值的过程须要漫长的时间。所以线程也无法继续运行下去,仅仅能等待。

2.2 js中的同步非堵塞

// 这是一个非堵塞式函数
// 假设复制已完毕。则返回 true, 假设未完毕则返回 false
function copyBigFile(afile,bfile){
var copying = copyFileAsync(afile, bfile);
var isFinished = !copying;
return !isFinished;
}

调用这个函数将立马返回结果,然后你的程序就能够写成

console.log("start copying ... ");
while( a = copyBigFile('A.txt', 'B.txt')){
console.log("在这之间还能够处理别的事情");
} ;
console.log("Finished"); // 这行程序将在一小时后运行
console.log("Hello World, 整个程序已载入完毕,请享用"); // 这行程序将在一小时后运行

一个非堵塞式的函数,给你的编程带来了很多其它的便利,你能够在长IO操作的同一时候。写点其它的程序,提高效率。运行结果例如以下

start copying ...
在这之间还能够处理别的事情
在这之间还能够处理别的事情
在这之间还能够处理别的事情
...
Finished
Hello World, 整个程序已载入完毕。请享用

2.3 js中的异步非堵塞

我们看到,一个非堵塞式的函数能给我们编程带来很多灵活性。我们喜欢非堵塞式的函数。

可是。又能够看到同步的程序须要在一个循环中轮询结果,循环里面的程序会被运行好多遍,所以并不好控制来写一些正常的程序,非常难再利用起来。

所以我们须要一种更为合理的方式对非堵塞式的函数进行利用。

也就是我不会主动地去询问结果,而是当你有了结果的时候再来通知我。

// 这是一个非堵塞式函数

// 假设复制已完毕,则返回 true, 假设未完毕则返回 false

//非堵塞式的有异步通知能力的函数
//下面不须要看懂,仅仅用知道这个函数会在完毕copy操作之后,运行success
function copyBigFile(afile,bfile, callback){
var copying = copyFileAsync(afile, bfile, function(){ callback();});
var isFinished = !copying;
return !isFinished;
}

这个函数不同于上一个同步非堵塞函数的地方在于。它具有通知功能,也就是说,它能够在完毕操作之后主动地通知程序,“我完毕了”。于是有程序例如以下,

console.log("start copying ... ");
copyBigFile("A.txt","B.txt", function(){
console.log("Finished"); //一个小时后被运行
console.log("Hello World, 整个程序已载入完毕,请享用"); //一个小时后被运行
})
console.log("干别的事情");
console.log("做一些别的处理");

程序在调用copyBigFile函数之后,能够立即获得返回值,线程没有被堵塞住,于是还能够去干些别的事情。然后当copyBigFile完毕之后。会运行指定的函数。

所以程序的输出应为,

start copying ...
干别的事情
做一些别的处理
Finished
Hello World, 整个程序已载入完毕。请享用

在这样的情况下。程序更easy控制,流程更为清晰。

一些“别的事情”能够在函数还未通知之前进行处理,充分地提高了线程的利用效率。

三、提升

在以上的程序中。我们的程序须要拷贝一个巨大的文件。事实上复制文件这个过程是留给系统的IO调用进行完毕的。而我们的线程并不须要去处理拷贝的细节。

所以通过非堵塞式的函数,我们能够 有可能 利用线程资源去干一下别的事情。

而通过异步调用方式。能使得程序流程 更easy控制,更有效率地利用线程资源。

而js是通过传递函数实现异步的。(还有能够通过promise的方式来实现异步…)

互联网我来了 -- 2. js中"异步/堵塞"等概念的简析的更多相关文章

  1. JS中的异步以及事件轮询机制

    一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...

  2. js中的异步与同步,解决由异步引起的问题

    之前在项目中遇到过好多次因为异步引起的变量没有值,所以意识到了认识js中同步与异步机制的重要性 在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程. 下面是j ...

  3. JS中的异步与回调

    问题的引出:在js中使用异步调用时,有可能会出现在异步的回调函数中设置调用之外的变量值,但在异步调用完成后去使用变量,却发现这些变量值并没有被成功设置的情况.如: google map中的地理编码,地 ...

  4. js中的异步[Important]

    js作为前端最主流的语言,主要处理页面显示变化(mutation)和异步(asynchronicity), js语言的基本要素和使用惯例的演化大都围绕着这两大主题,两者均值得总结和思考的主题, 这里先 ...

  5. JS中的异步

    Hello,日常更新的我“浪”回来了!!! JS中有三座高山:异步和单线程.作用域和闭包.原型原型链 今天“浪”的主题是JS中的异步和单线程的问题. 主要从这三个方面入手 一.什么是异步(与同步作比较 ...

  6. 咱们来聊聊JS中的异步,以及如何异步,菜鸟版

    为什么需要异步?why?来看一段代码. 问题1: for(var i=0;i<100000;i++){ } alert('hello world!!!'); 这段代码的意思是执行100...次后 ...

  7. promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

    * promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...

  8. js中的面向对象--类似于类的概念

    创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 使用object va ...

  9. 【第三周读书笔记】浅谈node.js中的异步回调和用js-xlsx操作Excel表格

    在初步学习了node.js之后,我发现他的时序问题我一直都很模糊不清,所以我专门学习了一下这一块. 首先我们来形象地理解一下进程和线程: 进程:CPU执行任务的模块.线程:模块中的最小单元. 例如:c ...

随机推荐

  1. 针对各地项目icomet停止服务的临时处理办法

    1.编辑一个脚本 vi /usr/local/watchicomet.sh #!/bin/bash sn=`ps -ef | grep ./icomet-server | grep -v grep | ...

  2. ./configure时候遇到的问题 Cannot find install-sh, install.sh, or shtool in ac-aux

    https://blog.csdn.net/anloan/article/details/17268997

  3. 解决iOS10的Safari下Meta设置user-scalable=no无效的方法

    苹果为了提高Safari中网站的辅助功能,屏蔽了Meta下的user-scalable=no功能.所以在iOS10下面,就算加上user-scalable=no,Safari浏览器也能支持手动缩放. ...

  4. Codeforces 914D Bash and a Tough Math Puzzle (ZKW线段树)

    题目链接  Round #458 (Div. 1 + Div. 2, combined)  Problem D 题意  给定一个序列,两种询问:单点修改,询问某个区间能否通过改变最多一个数使得该区间的 ...

  5. 洛谷——P1093 奖学金

    P1093 奖学金 题目描述 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生都有3门课的成绩:语文.数学.英语.先按总分从高到低排序,如果两个同学总分相 ...

  6. Xamarin XAML语言教程Progress属性设置进度条进度

    Xamarin XAML语言教程Progress属性设置进度条进度 在图12.19~12.21中我们看到的是没有实现加载的进度条,即进度条的当前进度为0,如果开发者想要修改当前进度,可以使用两种方式: ...

  7. 深入JS正则先行断言

    这里是 Mastering Lookahead and Lookbehind 文章的简单翻译,这篇文章是在自己搜索问题的时候stackoverflow上回答问题的人推荐的,看完觉得写得很不错.这里的简 ...

  8. Struts2笔记--Action访问Servlet API

    Web应用中通常需要访问的Servlet API就是HttpServletRequest.HttpSession和ServletContext,这三个接口分别代表JSP内置对象中的request.se ...

  9. 四. Java继承和多态3. 继承中的方法的覆盖和重载

    在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类 ...

  10. 代理模式(Proxy)--动态代理(JDK)

    在是上一篇博客中实现了静态代理. 在上篇的结尾提到了一个问题: 思考:如果我们下需要对火车,自行车实现相同的代理,我们又该如何实现呢? 这篇博客就来解决这个问题: 解决这类问题需要用到动态代理技术,实 ...