异步

  • 什么是单线程,和异步有什么关系
  1. 单线程——同一时间只能做一件事情
  2. 使用单线程原因——浏览器需要渲染dom,js可以修改dom结构,js执行时浏览器dom渲染会停止,两段js不能同时执行,为避免dom渲染冲突js只能单线程并且与浏览器渲染在同一个线程中。webworker支持多线程但不能访问dom
  3. 解决方案——异步
  • 什么是eventloop——事件轮询,js实现异步的具体解决方案
  1. 同步代码,直接执行
  2. 异步函数先放在异步队列中
  3. 待同步函数执行完毕,轮询执行异步队列中的函数
  4. 何时被放入异步队列(实际过程中,根据ajax、计时器等的具体时间决定谁优先执行)
  •  立即被放入
  • 指定时间后放入
  • ajax加载完成后放入
setTimeout(function(){
        console.log(200)
     },1000);
setTimeout(function(){
        console.log(100)
     });
     console.log(300);

//主进程
//console.log(300)               



//异步队列
//立刻被放入
function(){
        console.log(100)
     }


/1s后被放入
  function(){
       console.log(200)
     }
$.ajax({
       type : 'get',
       datatype:'json',       
       url : 'data.json',
        success: function(result){
           console.log("a")
      },
       error: function(){
           console.log("failed")}

   })
   setTimeout(function(){
        console.log(200)
     },10000);
     setTimeout(function(){
        console.log(100)
     });
   console.log(300);
   console.log(400);


主线程
console.log(300);
console.log(400);



异步队列
立即放入
function(){
        console.log(100)
     }
///监听……///
ajax获取到本地json,速度很快
function(result){
           console.log("a")

///监听……///
10000ms后被放入
function(){
        console.log(200)
     }
  • jquery的Deferred
简单封装
function waitHandle() {
    var dtd=$.Deferred()//创建一个deffered对象
    var wait=function(dtd){//要求传入一个deffered对象
      var task=function(){
        console.log("ok");
        dtd.resolve();//异步执行成功
        dtd.reject();//异步执行失败
        }
        setTimeout(task,2000);
         return dtd;//返回deffered对象
     }
     return wait(dtd);//这里一定要有返回值
  }
var w=new waitHandle();
w.then(function(){
    console.log('success1');
},function(){
    console.log('error');
})

jquery1.5的变化:

  1. 无法改变js异步和单线程的本质
  2. 只能在写法上杜绝callback这种形式
  3. 是语法糖,但是解藕了代码
  4. 很好的体现:开放封闭原则(对扩展开放,对修改封闭)
jquery1.5之前/
var ajax=$.ajax({
    url: "data.json",
    success:function(){
    console.log("success1");
    console.log('success2')
    },
    error: function(){
        console.log('error')
    }
})
console.log(ajax)//返回一个XHR对象



jquery1.5之后分为两类/
//第一类.done .fail// 
var ajax=$.ajax("data.json")
ajax.done(function(){
    console.log("success1");
    })
    .fail(function(){
        console.log('error')
    })
    .done(function () {
        console.log('success2')
      })
console.log(ajax)//返回一个Deffered对象

//第二类.then//
/与promise写法相似//
var ajax=$.ajax('data.json');
ajax.then(function(){
    console.log('success1')
},function(){console.log('fail1')})
     .then(function(){console.log('success 2'),
    function () {console.log('fail2')  }})



 

promise和deffered区别

function waitHandle() {
            var dtd=$.Deferred()//创建一个deffered对象
            var wait=function(dtd){//要求传入一个deffered对象
              var task=function(){
                console.log("ok");
                dtd.resolve();//异步执行成功
                dtd.reject();//异步执行失败
                }
                setTimeout(task,2000);
                 return dtd.promise();//返回promise对象
             }
             return wait(dtd);//这里一定要有返回值
          }
        var w=new waitHandle();
        //  w.reject();报错,使用者不能干扰promise的成功还是失败
        w.then(function(){
            console.log('success1');
        },function(){
            console.log('error');
        })

两大类:第一类:.reject .resolve
     第二类:.done .fail .then 
两类不能混用
使用者不能干扰promise的成功还是失败
  • Promise的基本使用和原理
  • Promise状态变化
  1. 三种状态:pending,fulfilled,rejected
  2. 初始状态是pending,pending转变为fulfilled,pending转变为rejected,状态不可逆
  3. Promise实例必须实现then的方法,then()必须接收两个函数作为参数,then()必须返回一个Promise实例
  4. 如果then()中函数没有明文返回一个Promise实例,那么返回的就是调用这个.then()本身的Promise实例;如果then()中函数明文返回一个不同的Promise实例,那么后面再执行.then()时返回的就是这个新的Promise()实例
 function Img(src){
     const promise=new Promise(function (resolve,reject) {
         var img=document.createElement('img');
         img.src=src;
         img.onload=function(){
             console.log('ok');
             resolve(img);
         }
         img.onerror=function(){
             reject();
         }
       })
       return promise;
 }
 var src="https://www.imooc.com/static/img/index/logo.png";
 var result=Img(src);
 result.then(function (img)
 {
     console.log(img.height);
     return img;
 },
function(){
    console.log('fail');
})

异常捕获

function Img(src){
     const promise=new Promise(function (resolve,reject) {
         var img=document.createElement('img');
         img.src=src;
         img.onload=function(){
             console.log('ok');
             resolve(img);
         }
         img.onerror=function(){
             reject("失败");
         }
       })
       return promise;
 }
 var src=" ";//不添加图片路径
 var result=Img(src);
 result.then(function (img)
 {
     console.log(img.height);
     return img;
 }).catch(function(ex){//onerror事件或其他异常都通过异常捕获.catch来监听,在.then中只添加加载完成的onload事件
    console.log(ex);
})

多个串联

 function Img(src){
     const promise=new Promise(function (resolve,reject) {
         var img=document.createElement('img');
         img.src=src;
         img.onload=function(){
             console.log('ok');
             resolve(img);
         }
         img.onerror=function(){
             reject("失败");
         }
       })
       return promise;
 }
 var src1="https://www.imooc.com/static/img/index/logo.png";
 var src2="https://www.imooc.com/static/img/common/appload.png";
 var result1=Img(src1);
 var result2=Img(src2);
 result1.then(function (img1){
     console.log("第一个图片加载完成",img1.width);
     return result2;//如果then()中函数没有明文返回一个Promise实例,那么返回的 
                   //就是调用这个.then()本身的Promise实例;如果then()中函数明 
                   //文返回一个不同的Promise实例,那么后面再执行.then()时返回 
                   //的就是这个新的Promise()实例
 }).then(function (img2) {//此时.then()相当于result2.then()
     console.log("第二个图片加载完成",img2.width)
   }).catch(function(ex){
        console.log(ex);
})

Promise.all&Promise.race

Promise.all执行数组内的所有promise对象,Promise.race只执行数组内优先加载完成的第一个promise对象

 function Img(src){
     const promise=new Promise(function (resolve,reject) {
         var img=document.createElement('img');
         img.src=src;
         img.onload=function(){
             console.log('ok');
             resolve(img);
         }
         img.onerror=function(){
             reject("失败");
         }
       })
       return promise;
 }
 var src1="https://www.imooc.com/static/img/index/logo.png";
 var src2="https://www.imooc.com/static/img/common/appload.png";
 var result1=Img(src1);
 var result2=Img(src2);
 Promise.all([result1,result2]).then(function(datas){
     console.log(datas[0])
     console.log(datas[1])
 })
 Promise.race([result1,result2]).then(function(data){
    console.log(data)
 })
  • async/await(和promise的区别、联系)

then只是将callback代码拆分了,async/await用同步写法实现异步操作

使用await,函数必须用async标识,await后面跟的是一个Promise实例,需要babel-polyfill

使用了Promise并没有和Promise冲突,完全是同步的写法,再也没有回调函数,改变不了js单线程、异步的本质

 function Img(src){
     const promise=new Promise(function (resolve,reject) {
         var img=document.createElement('img');
         img.src=src;
         img.onload=function(){
             console.log('ok');
             resolve(img);
         }
         img.onerror=function(){
             reject("失败");
         }
       })
       return promise;
 }
 var src1="https://www.imooc.com/static/img/index/logo.png";
 var src2="https://www.imooc.com/static/img/common/appload.png";
 const load=async function(){
     const result1=await Img(src1);
     console.log(result1);
     const result2=await Img(src2);
     console.log(result1);
 }
 load();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值