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的优点显而易见。

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

    参考文献

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

  • 相关阅读:
    计算机硬件内存双通道只显示一根内存条,不能组成双通道
    VMware 虚拟机安装win10操作系统系列问题解决
    编译语言和解释语言区别
    SPSS 24下载与安装+授权码
    Reg文件操作
    DLL注册表文件相关内容
    安装TensorFlow失败
    Anaconda 包管理与环境管理
    Cookie设置域名问题,cookie跨域
    准备篇(二)C语言
  • 原文地址:https://www.cnblogs.com/can-i-do/p/7138105.html
Copyright © 2011-2022 走看看