(二)异步解决方案之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{
  width: 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的优点显而易见。

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

参考文献

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

转载于:https://www.cnblogs.com/can-i-do/p/7138105.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值