互联网我来了 -- 2. js中"异步/阻塞"等概念的简析
2015-03-16 11:40
260 查看
一、什么是”异步非阻塞式”?
这个名字听起来很恶心难懂,但如果以 买内裤 这件事情来比喻执行程序的话就很容易理解“异步非阻塞式”的涵义了。例如你是一个CPU的线程,你需要去执行一段 买内裤的程序, 你所需执行的步骤大致如下,
到一个商店里问老板, 你们店里还有没有nb牌内裤?
买到内裤,穿上
去小卖店买点火腿回家喂狗
这时候,你作为一个线程,你可能会遇到几种状况或选择。
店里面没货了,老板一直不答应你(阻塞你),你也一直等着(同步),第三天有货了才告诉你有了,你赶紧拿到穿上,再去买火腿 – [同步阻塞模式]
老板马上告诉你“没货了”(不阻塞你),然后你每天去店里问一声,直到有货了赶紧穿上,再去买东西喂狗 – [同步非阻塞]
你让老板有货了打电话叫你过来取,老板说“好的”(非阻塞),然后你就先去买东西喂狗了,过了两天老板叫你过去,你才拿到内裤并穿上 – [异步非阻塞]
你让老板有货了打电话叫你过来取, 老板又没答应你(阻塞), 然后你本来打算去先去买火腿的(异步),这时候也没法去了。 – [异步阻塞]
很明显,第三种方法是最聪明,前两种方法都略显效率低下。所以根据我们的理解,
同步或非同步,表明着是否需要将整个流程顺序地完成
阻塞或非阻塞,意味着你调用的函数会不会立刻告诉你结果
二、在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, 整个程序已加载完毕,请享用
在这种情况下,程序更容易控制,流程更为清晰。一些“别的事情”可以在函数还未通知之前进行处理,充分地提高了线程的利用效率。
三、提升
在以上的程序中,我们的程序需要拷贝一个巨大的文件。其实拷贝文件这个过程是留给系统的IO调用进行完成的,而我们的线程并不需要去处理拷贝的细节。所以通过非阻塞式的函数,我们能够 有可能 利用线程资源去干一下别的事情。
而通过异步调用方式,能使得程序流程 更容易控制,更有效率地利用线程资源。
而js是通过传递函数实现异步的。(还有可以通过promise的方式来实现异步…)
相关文章推荐
- 互联网我来了 -- 2. js中"异步/堵塞"等概念的简析
- 互联网我来了 -- 2. js中"异步/阻塞"等概念的简析
- “阻塞”与"非阻塞"与"同步"与“异步
- "互联网地图"诞生十周年 路由器数量已增5倍
- 同步、异步、阻塞和非阻塞的概念
- 互联网知识价值化公式-"龙"公式
- 奇虎周鸿祎:互联网公司应主动"锻炼"积极"过冬"
- 互联网大鳄的"打"、"着实打"、"用心打"
- 初步认识 "云计算" 概念
- 互联网大鳄的"打"、"着实打"、"用心打"
- 奇虎周鸿祎:互联网公司应主动"锻炼"积极"过冬"
- 奇虎周鸿祎:互联网公司应主动"锻炼"积极"过冬"
- 同步、异步、阻塞和非阻塞的概念
- 互联网大鳄的"打"、"着实打"、"用心打"
- 互联网大鳄的"打"、"着实打"、"用心打"
- 2008年成互联网"开放年" 校内网推开放平台
- 同步、异步、阻塞和非阻塞的概念
- [转载]同步、异步、阻塞和非阻塞的概念
- 云计算:互联网上空飘来几朵"云"
- 转载于"网眼"---网页游戏“贪食蛇”简析