原型异步一、什么是单线程,和异步有什么关系单线程:只有一个线程,同一时间只能做一件事原因:避免DOM渲染的冲突解决方案:异步为什么js只有一个线程:避免DOM渲染冲突浏览器需要渲染DOMJS可以修改DOM结构JS执行的时候,浏览器DOM渲染会暂停两端JS也不能同时执行(都修改DOM就冲突了)webworker支持多线程,但是不能访问DOM 解决方案存在的问题问题一:没按照书写方式执行,可读性差问题二:callback中不容易模块化二、什么是event-loop事件轮询,JS实现异步的具体解决方案同步代码,直接执行异步函数先放在异步队列中待同步函数执行完毕,轮询执行异步队列的函数setTimeout(function(){ console.log(1);},100); //100ms之后才放入异步队列中,目前异步队列是空的setTimeout(function(){ console.log(2); //直接放入异步队列})console.log(3) //直接执行//执行3之后,异步队列中只有2,把2拿到主线程执行,2执行完之后,异步队列中并没有任务,所以一直轮询异步队列,直到100ms之后1放入异步队列,将1拿到主线程中执行$.ajax({ url:’./data.json’, success:function(){ //网络请求成功就把success放入异步队列 console.log(‘a’); }})setTimeout(function(){ console.log(‘b’)},100)setTimeout(function(){ console.log(‘c’);})console.log(’d’)//打印结果://d //d //c //c //a //b //b //a //真实环境不会出现dacb三、是否用过jQuery的DeferredjQuery1.5的变化使用jQuery Deferred初步引入Promise概念 jQuery1.5之前var ajax = $.ajax({ url:’./data.json’, success:function(){ console.log(‘success1’); console.log(‘success2’); console.log(‘success3’); }, error:function(){ console.log(’error’); }})console.log(ajax); //返回一个XHR对象 jQuery1.5之后var ajax = $.ajax(’./data.json’);ajax.done(function(){ console.log(‘success1’)}).fai(function(){ console.log(‘fail’)}).done(function(){ console.log(‘success2’);})console.log(ajax); //deferred对象var ajax = $.ajax(’./data.json’);ajax.then(function(){ console.log(‘success1’)},function(){ console.log(’error1’);}).then(function(){ console.log(‘success2’);},function(){ console.log(’error’);})//使用var w = waithandle()w.then(function(){ console.log(‘ok1’);},function(){ console.log(’err2’);}).then(function(){ console.log(‘ok2’);},function(){ console.log(’err2’);})//还有w.wait w.fail无法改变JS异步和单线程的本质只能从写法上杜绝callback这种形式它是一种语法糖,但是解耦了代码很好的提现:开放封闭原则(对扩展开放对修改封闭)使用jQuery Deferred//给出一段非常简单的代码,使用setTimeout函数var wait = function(){ var task = function(){ console.log(‘执行完成’); } setTimeout(task,2000)}wait();//新增需求:要在执行完成之后进行某些特别复杂的操作,代码可能会很多,而且分好几个步骤function waitHandle(){ var dtd = $.Deferred();//创建一个deferred对象 var wait = function(dtd){ // 要求传入一个deferred对象 var task = function(){ console.log(“执行完成”); dtd.resolve(); //表示异步任务已完成 //dtd.reject() // 表示异步任务失败或者出错 }; setTimeout(task,2000); return dtd; } //注意,这里已经要有返回值 return wait(dtd);}/**总结:dtd的API可分成两类,用意不同第一类:dtd.resolve dtd.reject第二类:dtd.then dtd.done dtd.fail*这两类应该分开,否则后果严重!可以在上面代码中最后执行dtd.reject()试一下后果/使用dtd.promise()function waitHandle(){ var dtd = $.Deferred(); var wait = function(){ var task = function(){ console.log(‘执行完成’); dtd.resolve(); } setTimeout(task,2000) return dtd.promise(); //注意这里返回的是promise,而不是直接返回deferred对象 } return wait(dtd)}var w = waitHandle(); //promise对象$.when(w).then(function(){ console.log(‘ok1’);},function(){ console.log(’err1’);})/只能被动监听,不能干预promise的成功和失败/可以jQuery1.5对ajax的改变举例说明如何简单的封装、使用deferred说明promise和Defrred的区别要想深入了解它,就需要知道它的前世今生四、Promise的基本使用和原理基本语法回顾异常捕获//规定:then只接受一个函数,最后统一用catch捕获异常多个串联var scr1 = ‘https://www.imooc.com/static/img/index/logo_new.png';var result1 = loadImg(src1);var src2 = ‘https://www.imooc.com/static/img/index/logo_new.png';var result2 = loadImg(src2);result1.then(function(img1) { console.log(‘第一个图片加载完成’, img1.width); return result2;}).then(function(img2) { console.log(‘第二个图片加载完成’, img2.width);}).catch(function(ex) { console.log(ex);})Promise.all和Promise.race//Promise.all接收一个promise对象的数组//待全部完成后,统一执行successPromise.all([result1, result2]).then(datas => { //接收到的datas是一个数组,依次包含了多个promise返回的内容 console.log(datas[0]); console.log(datas[1]);}) //Promise.race接收一个包含多个promise对象的数组//只要有一个完成,就执行successPromise.race([result1, result2]).then(data => { //data即最先执行完成的promise的返回值 console.log(data);})Promise标准三种状态:pending,fulfilled,rejected初始状态:pendingpending变为fulfilled,或者pending变为rejected状态变化不可逆promise必须实现then这个方法then()必须接收两个函数作为标准then五、介绍一下async/await(和Promise的区别、联系)六、总结一下当前JS结局异步的方案虚拟DOMMVVM和vue组件化和Reacthybrid未完待续,每日更新