zoukankan      html  css  js  c++  java
  • (二)异步解决方案之callback

    回调定义

    就是一个函数里面使用 作为参数的函数。
    Function1(Function2) {
    Function2();
    };

    同步调用 - 老实说,这和我们 不将代码封装成 函数没有差别

    也就是说 其实它 只是为了 将代码拆分。(也许是功能应该被拆,也许是代码太长)

    const chooseHeroA = () => {
      console.log('choose a');
    }
    const chooseHeroB = () => {
      console.log('choose b');
    }
    chooseHeroA();
    chooseHeroB();
    

    同步调用

    const chooseHeroA = (callback) => {
      console.log('choose a');
      callback && callback();
    }
    const chooseHeroB = () => {
      console.log('choose b');
    }
    chooseHeroA(chooseHeroB);
    

    异步调用 - 调用就是调用,但是 利用上了 异步的方法,那就叫异步调用了

    比如 setTimeout 的异步实现方法

    const chooseHeroA = (callback) => {
      setTimeout(callback, 1000);
      console.log('choose a');
    }
    const chooseHeroB = () => {
      console.log('choose b');
    }
    chooseHeroA(chooseHeroB);
    

    关于顺序: 这个顺序主要是表明。 虽然 a 在 b 代码之后,但是因为是异步的,所以并不会产生 前面的代码 阻塞 后面的代码的清空。
    通过这样,它的功能显而意见,防止 超级麻烦的代码阻塞了代码的执行。

    const chooseHeroA = (callback) => {
      setTimeout(callback, 0);
      console.log('choose a');   //  a , b
    }
    const chooseHeroB = () => {
      console.log('choose b');
    }
    chooseHeroA(chooseHeroB);
    

    于是我们放一个什么叫超级麻烦的代码吧,比如说 无限的 for循环?还是不要无限了,给电脑放个假

    const advantageAsync = (callback) => {
      for (i = 0; i < 1000000000; i++) {};
      console.log('choose a');
    }
    advantageAsync();
    

    如果你的电脑很快就执行完了上面的代码,那说明你的电脑够好,它的数字还不够大

    但是我的老人机已经露出了破绽。

    于是,异步有了用武之地.

    const advantageAsync = (callback) => {
      setTimeout(() => {
        for (i = 0; i < 1000000000; i++) {};
      }, 0);
      console.log('choose a');
    }
    advantageAsync();
    

    回调,其实往往用在异步的使用上,是前端在 刀耕火种 时期的异步方式。

    但是它的缺陷也很明显.

    那么,游戏开始,来完成一个 小球动画吧(来自 慕课网 里的一个教程,改)

    css

    .ball{
       40px;
      height: 40px;
      border-radius: 20px;
    }
    .ball1{
      background: red;
    }
    .ball2{
      background: yellow;
    }
    .ball3{
      background: blue;
    }
    

    html

    <div class="ball ball1"></div>
    <div class="ball ball2"></div>
    <div class="ball ball3"></div>
    

    js

    const ball1 = document.querySelector(".ball1");
    const ball2 = document.querySelector(".ball2");
    const ball3 = document.querySelector(".ball3");
    
    const getStyle = (ele, attr) => {
      if (window.getComputedStyle) {
        return window.getComputedStyle(ele, null)[attr];
      } else {
        return ele.currentStyle[attr];
      }
    };
    
    const Move = (ball, target, next) => {
      setTimeout(() => {
        let marginLeft = parseInt(getStyle(ball, "marginLeft"));
        if (marginLeft === target) {
          next && next();
        } else {
          if (marginLeft < target) {
            marginLeft ++;
          } else {
            marginLeft --;
          }
    
          ball.style.marginLeft = marginLeft + "px";
          Move(ball, target, next);
        }
      }, 10);
    };
    
    Move(ball1, 100, function() {
      Move(ball2, 200, function () {
        Move(ball3, 300);
      })
    });
    

    其实,我们只看 最后的 几行,我们就能够 明白,当操作一多,这是个什么情景。

    其实 Promise,解决的就是这个缩进问题。

    还是上面的 html 和 css,改的是 js部分的

    const ball1 = document.querySelector(".ball1");
    const ball2 = document.querySelector(".ball2");
    const ball3 = document.querySelector(".ball3");
    
    const getStyle = (ele, attr) => {
      if (window.getComputedStyle) {
        return window.getComputedStyle(ele, null)[attr];
      } else {
        return ele.currentStyle[attr];
      }
    };
    
    const Promise = window.Promise;
    
    const promiseAnimate = (ball, target) => {
      return new Promise((resolve, reject) => {
          const auto = (ball, target) => setTimeout(() => {
            let marginLeft = parseInt(getStyle(ball, "marginLeft"));
            if (marginLeft === target) {
              resolve();
            } else {
              if (marginLeft < target) {
                marginLeft ++;
              } else {
                marginLeft --;
              }
              ball.style.marginLeft = marginLeft + "px";
              auto(ball, target);
            }
          }, 10);
    
          auto(ball, target);
      });
    };
    
    promiseAnimate(ball1, 100)
    .then(() => {
      return promiseAnimate(ball2, 200);
    })
    .then(() => {
      return promiseAnimate(ball3, 300);
    });
    

    Promise的优点显而易见。

    换了个写法?是的,就是如此。
    没有嵌套就是可以为所欲为。

    参考文献

    烽火传递-超级好的一篇文章

  • 相关阅读:
    6. Flask请求和响应
    5. Flask模板
    FW:Software Testing
    What is the difference between modified duration, effective duration and duration?
    How to push master to QA branch in GIT
    FTPS Firewall
    Query performance optimization of Vertica
    (Forward)5 Public Speaking Tips That'll Prepare You for Any Interview
    (转)The remote certificate is invalid according to the validation procedure
    Change
  • 原文地址:https://www.cnblogs.com/can-i-do/p/7138105.html
Copyright © 2011-2022 走看看