前言
JS的异步由来已久,各种异步概念也早早堆在开发者面前。可现实代码中,仍然充斥了各种因异步顺序处理不当的bug,或因不好好思考,或因不了解真相。今天,就特来再次好好探索一番JS的异步世界。
01 异步的由来--单线程
上世纪末,互联网仍处于极慢速时代,穿梭于客户端与服务端的请求,对于时间的耗费是如此的奢侈。而即将面世的LiveScript,便被网景公司考虑同时在浏览器和服务端使用,在浏览器端对表单进行校验,从而提高表单提交效率。为了将这一脚本语言推向市场,网景与sun联合开发,最终以Java冠名为JavaScript。
刚面世的JavaScript,是为网页设计人员准备的,不需要太复杂的语言设计,能简单上手,自然就是最好的。
于是,单线程,弱类型,一开始就成为了JavaScript的基因。而其中的单线程,便是最戏剧性的存在,Ryan Dahl因为JavaScript是单线程语言,从而选择了js开发了轻量级服务器(nodejs),使得js从浏览器端延伸到服务器。随着JS开发队伍和程序复杂度的同步发展,异步处理成为了JS程序的重中之重。
02 JS是一个充满异步的世界
先来导入几个异步的常见场景
dom用户输入响应
ducument.addEventListener('click', function(){})
Ajax
$.ajax(<url>, function() {})
定时/延时
setTimeout(function() {}, 1000) setInterval(function() {}, 1000)
文件读取
var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function() {}
以上的场景基本有个共同特性,耗时!
举个栗子,我们去银行取钱,当人很多时,如果还是排队模式,会耗费很多时间(同步模式)。于是设立了取号机,取了号,不用排队,在一旁坐着,安心打开电脑写个文档,等叫号后再去办业务(异步模式)。
同理,由于单线程的特性,当JS应用越来越复杂,耗时的程序如果以同步来进行,就会阻塞js的单线程,如大水冲过狭窄的河道,势必决堤。那JS是怎么开拓导流渠道的呢?其实在js的单线程(主线程)背后,规律的运行了很多线程:
- dom事件处理线程
- http请求线程
- 定时器线程
- ...