제8주 이튿날 필기

14897 단어
ES6의 Promise 클래스
1 Promise 클래스 기초 지식 해독
  • promise류의 정적 속성 방법
  • 분류:resolve(),reject(),all(),race()
  • resolve(): 형참으로 실례 대상에 전송하고 조건이 충족될 때 리셋 함수로 실행하여 실참으로 전송할 수 있다.then의 첫 번째 매개 변수 리셋 함수 수신;
  • reject(): 형참으로 실례 대상에 전송되고 조건이 충족되지 않을 때, 즉 실패할 때 리셋 함수로 집행되며 실참,then의 두 번째 매개 변수 리셋 함수로 수신하거나catch의 리셋 함수로 수신할 수 있다.
  • all(): 비동기 조작을 병행하여 실행하는 능력을 제공하고 모든 비동기 조작이 실행된 후에야 리셋을 실행한다. 즉, 가장 느린 것이 실행되지 않았을 때 실행된 비동기 조작이 전송된 데이터는 수조의 형식으로 저장하고 가장 느린 것이 실행된 후에 하나의 수조의 형식으로 데이터를then으로 전송한다.
  • race(): 여러 개의 비동기 조작은 똑같이 병행적으로 실행되고 누가 가장 빠르면 데이터가then에 들어간다.다른 비동기 조작은 계속 실행되지만then은 다른 비동기 조작의 데이터를 더 이상 받아들일 수 없습니다.

  • 사용:Promise 클래스 이름 호출, 즉Promise.all;실례 대상은 사용할 수 없습니다.

  • promise류 원형의 속성 방법
  • 분류:then(),catch()
  • then(): 첫 번째 인자는 리셋 함수이고 비동기 조작이 성공한 후resolve가 전송한 인자를 얻을 수 있다. 두 번째 인자는 있어도 되고 없어도 된다. 만약에 추가하면 리셋 함수이다. 그 안에 받은 것은 비동기 조작이 실패한 후reject가 전송한 인자이다.
  • catch(): 하나의 매개 변수를 받아들이는 것은 리셋 함수이고 첫 번째 기능은 비동기 조작이 실패한 후reject가 전송한 매개 변수를 받는 것이다.두 번째 기능은 비동기 조작이 성공하면 then에 들어가지만 then에서 코드를 실행하고 오류를 보고한 다음에catch는 오류를 보고한 텍스트를 받아서 JS를 중지하지 않고 JS가 계속 실행될 수 있도록 보장한다.

  • 사용: 실례 대상만 원형의 속성 방법을 사용할 수 있다.

  • 총괄: 실례 창설에서 조건이 충족되면 Resolve()를 실행하고then에서 익명 함수 호출에 해당한다.리셋 함수에 해당하고resolve는then의 익명 함수의 함수명으로 볼 수 있다.비동기 조작은 사실 실례 대상이 스스로 실행하는 것이다.
  • Promise 상세 판독 파일
  • 2 Promise 클래스 인스턴스
  • 인스턴스 1: 이미지 요청 시간 초과
  • 지식점: 두 개의 비동기 조작을 레이스 방법에 넣고 5초 안에 그림 요청이 성공하면then 방법에 들어가 정상적인 절차를 수행한다.만약 5초 동안 그림이 성공적으로 되돌아오지 않았다면, imgTimeout이 가장 빨리 실행되면catch에 들어가서 '그림 요청 시간 초과' 정보를 알립니다.RequestImg 함수에서 그림 주소가 잘못되면 그림을 정상적으로 불러올 수 없습니다.onload 이벤트는 실행되지 않으며,resolve는 실행되지 않기 때문에then에 들어가지 않습니다.
  •    
        function requestImg() {
            return new Promise(function (resolve) {
                var oImg=new Image();
                oImg.onload=function(){
                   resolve(this);
                };
                oImg.src="image1/01.png";
            })
        }
        function imgTimeout() {
            return new Promise(function (resolve, reject) {
                setTimeout(function () {
                    reject("      ");
                },5000)
            })
        }
        Promise.race([requestImg(),imgTimeout()])
            .then(function (data) {
                document.body.appendChild(data);
            })
            .catch(function (reason) {
                console.log(reason);
            });
       
    
  • 실례2: 소구 운동 실례
  • 지식점: 비동기 조작을 여러 번 실행하고 비동기 조작 1을 실행한 후 조건이 충족되면 비동기 조작 1에서resolve()를 실행하고 비동기 조작 1점then의 익명 함수에서 다른 비동기 조작 2를 되돌려준다.그리고 비동기 동작 2를 실행하고 실질적으로 실례 대상의 자체 실행을 한 다음에 조건을 충족시킬 때 비동기 동작 2의resolve()를 실행한 다음에 비동기 동작 2점then의 익명 함수에서 비동기 동작 3을 되돌려주고 마지막 비동기 동작에서 조건이 충족될 때까지 비동기 동작 2의resolve()를 실행하고 그 뒤의then 익명 함수에서운동 종료 코드 추가하기;
  •  
     
     
         
               
         
     
     
     
    var oDiv1=document.getElementsByTagName("div")[0]; var oDiv2=document.getElementsByTagName("div")[1]; var oDiv3=document.getElementsByTagName("div")[2]; //ele: ;target: function promiseAnimate(ele,target) {// //resolve: ,reject: return new Promise(function(resolve,reject){ function animate() {// setTimeout(function () { var n=parseFloat(ele.style.marginLeft); if(n===target){ resolve();// }else{ if(n<target){ n++; ele.style.marginLeft=n+"px"; }else{ n--; ele.style.marginLeft=n+"px"; } animate(); } },10); } animate();// ; }) } promiseAnimate(oDiv1,100) .then(function () { return promiseAnimate(oDiv2,200) }) .then(function () { return promiseAnimate(oDiv3,300) }) .then(function () { return promiseAnimate(oDiv3,150) }) .then(function () { return promiseAnimate(oDiv2,150) }) .then(function () { return promiseAnimate(oDiv1,150) }) .then(function () { alert(" ") })

    运动库

    • 实例1:左右按钮点击运动
      • 知识点:
        • 边界值的判断:1)在cur累加累减之前,必须加减步长进行判断;2)在cur累加累减之后,不用加减步长进行判断,直接判断cur是否满足条件;
        • 边界值判断条件成立,执行的语句中,设置边界值,然后添加return,阻断程序执行;
        • 需注意:设置样式值,必须在边界值判断之后;;
         
          //1      , cur      ,          ;
          if(cur>target){
              if(cur-5<=target){//          ,            ;
                  oDiv.style.left=target+"px";
                  return;
              }
              cur-=5;
          }else{
              if(cur+5>=target){
                  oDiv.style.left=target+"px";
                  return;
              }
              cur+=5;
          }
          oDiv.style.left=cur+"px";
         //2      , cur      ,          ,    cur      ,         ,           ;
         if(cur>target){
             cur-=5;
             if(cur<=target){//             ,            ;
               oDiv.style.left=target+"px";
               return;
              }
         }else{
             cur+=5;
             if(cur>=target){
               oDiv.style.left=target+"px";
               return;
              }
         }
         oDiv.style.left=cur+"px";
         
        
      • 타이머의 timer, 요소의 사용자 정의 속성에 설정하여 전역 변수를 피한다
      • 두 개의 클릭 이벤트가 하나의 타이머를 실행할 때 문제가 발생하기 때문에 타이머를 실행하기 전에 타이머를 닫아야 한다.
      • 최적화 사상:
      • 에 나타난 문제: 타이머에 함수의 정의 단계를 추가하고 괄호를 넣지 않지만 파라미터가 있는 함수에 대해서는 함수 이름만 쓸 수 없고 익명 함수를 새로 만들어서 익명 함수에 호출할 수 있다.예를 들어 oDiv.timer=setTimeout(function(){ moveBat(target);},30), 그러나 이렇게 설정하면 문제가 발생할 수 있습니다. 타이머의moveBat(target) 실행 값이 있으면 매개 변수 target을 찾고 익명 함수를 찾습니다. 상위 역할 영역을 찾을 수 없습니다. 이 때 타이머의 익명 함수로 이루어진 개인 역할 영역은 방출되지 않습니다. 타이머를 실행할 때마다 개인 역할 영역을 새로 만듭니다.그래서 메모리가 커서 최적화에 불리하다.
      • 해결 조치:moveBat(target) 함수 정의에 새로운 함수 추가move(), 모든 코드를 넣고 타이머에 추가move, 이렇게 하면 타이머가 실행될 때 중복 호출됩니다move 함수;더 이상 익명 함수가 형성되지 않음;하지만 주의해야 할 것은move 정의 단계 후 한 번 실행해야 합니다.


      • 코드:
      •  
         
         
             
                     
             
         
         
         
        var oDiv=document.getElementById("div1"); var aBtn=document.getElementsByTagName("button"); aBtn[0].onclick=function () { moveBat(250); }; aBtn[1].onclick=function () { moveBat(1150); }; function moveBat(target) { _moveBat();// ; function _moveBat(){// , var cur=oDiv.offsetLeft; if(cur>target){ if(cur-5<=target){// , ; oDiv.style.left=target+"px"; return; } cur-=5; }else{ if(cur+5>=target){ oDiv.style.left=target+"px"; return; } cur+=5; } oDiv.style.left=cur+"px"; clearTimeout(oDiv.timer);// ; oDiv.timer=setTimeout(_moveBat,30);// timer , ; } /* oDiv.timer=setTimeout(function () {// , , , moveBat(target); },30);*/ } //1 , ; //2 timer, , //3 , , ; //4 ;
      • 运动库linear函数封装
        • 目的:获取运动元素的实时位置
        • 参数:
          • b:begin 运动起始位置
          • c:change 还要走多远
          • d:duration 走完剩下的路程需要的总时间
          • t:time 代表走了多少时间
        • 变量:time值为可变值,不断地累加,然后计算出实时位置;配合定时器使用;
        • 返回值:返回实时位置值;
         
           function linear(c,d,t,b) {
               return c/d*t+b;
           }
         
        
      • 인스턴스
      •  
             function linear(c,d,t,b) {
                 return c/d*t+b;
             }
             var oDiv1=document.getElementById("div1");//    
             var oDiv2=document.getElementById("div2");//      
             //   target    
             var target=oDiv2.offsetLeft-oDiv1.offsetWidth-oDiv2.offsetWidth;//               ;
             var b=oDiv1.offsetLeft;
             var c=target-b;
             var d=1000;
             var t=0;
             oDiv1.timer=setInterval(function () {
                 t+=10;//time   ,    ;
                 //     
                 if(t>d){
                     oDiv1.style.left=target+"px";
                     clearInterval(oDiv1.timer);
                 }
                 var curLeft=linear(c,d,t,b);
                 oDiv1.style.left=curLeft+"px";
             },10)
         
        
      • 실례: 한 물체의 다운동
      • 목적: 한 물체가 x, y 두 방향에서 동시에 고른 속도로 운동하는 것을 실현한다.
      • 사고방식:
      • 물체가 x, y방향에서 운동하는 시작 위치, 목표 위치를 구하고 각 방향의 총 노정을 산출한다.
      • 총 시간duration 설정;
      • 시작 시간은 0, 즉time 초기 부여값은 0이다.
      • 타이머 설정: 1) 타이머 변수의 누적을 진행하려면 타이머의 실행 시간과 같은 것이 좋다.2) 경계점 판단(목표 위치 설정, 타이머 정지, 프로그램 실행 차단);3)linear 방법을 이용하여 x, y방향의 실시간 위치를 얻기;4) 실시간 위치 설정하기;

      •  
         
         
             
                     
             
         
         
         
        function linear(c,d,t,b) { return c/d*t+b; } var oDiv1=document.getElementById("div1"); var oDiv2=document.getElementById("div2"); var targetLeft=oDiv2.offsetLeft-oDiv1.offsetWidth,targetTop=oDiv2.offsetHeight+oDiv2.offsetTop-oDiv1.offsetHeight; var beginLeft=oDiv1.offsetLeft,beginTop=oDiv1.offsetTop; var changLeft=targetLeft-beginLeft,changTop=targetTop-beginTop; var duration=1000; var time=0; var timer=setInterval(function () { //1 time+=10; //2 if(time>=duration){ // utils.css(oDiv1,{ left:targetLeft, top:targetTop }); // clearInterval(timer); // return ; } //3 var curLeft=linear(changLeft,duration,time,beginLeft); var curTop=linear(changTop,duration,time,beginTop); //4 utils.css(oDiv1,{ left:curLeft, top:curTop }); },10);
      • 实例:封装方法,实现物体的多运动库
        • 参数: ele:元素,target:目标值,对象,duration:运动总时间
        • 注意点:
          • 工具库的引用,需要按照引用顺序调用;
          • 在工具库中利用自执行函数封装的方法,需要设置window,将其设置成全局变量,这样才能在全局引用;
        • 工具库代码:
         (function () {
             var gbEffect={
                 Linear:function(c,d,t,b){
                     return c/d*t+b;
                 }
             };
             function move(ele,target,duration){
                 //ele:  ,target:   ,  ,duration:  
                 duration=duration || 2000;
                 var begin={},change={};
                 for(var attr in target){
                     begin[attr]=utils.css(ele,attr);
                     change[attr]=target[attr]-begin[attr];
                 }
                 var time=0;
                 //   
                 var timer=setInterval(function () {
                     //    
                     time+=10;
                     //     
                     if(time>=duration){
                         //     
                         console.log(1)
                         utils.css(ele,target);
                         //     
                         clearInterval(timer);
                         //      
                         return ;
                     }
                     //      
                     for(var attr in change){
                         var linear=gbEffect.Linear(change[attr],duration,time,begin[attr]);
                         //      
                         utils.css(ele,attr,linear);
                     }
                 },10)
             }
             //            ,  window     
             window.animate=move;
         })();
        
      • 실행 코드:
      • var oDiv1=document.getElementById("div1"); var oDiv2=document.getElementById("div2"); animate(oDiv1,{ left:oDiv2.offsetLeft-oDiv1.offsetWidth, top:oDiv2.offsetTop+oDiv2.offsetHeight-oDiv1.offsetHeight, opacity:0.8 },2000)

    좋은 웹페이지 즐겨찾기