引入

需求:编写一个 delay 延迟函数,执行 delay 函数,可以把我们要做的事情延迟一段时间执行

解决方案:基于“回调函数”的方式来管理

  1. const delay = function delay(interval, callback) {
  2. // 处理参数
  3. if (typeof interval === 'function') {
  4. callback = interval
  5. interval = 1000
  6. }
  7. if (typeof callback !== 'function') throw new TypeError('callback is not a function')
  8. interval = +interval
  9. if (isNaN(interval)) interval = 1000
  10. // 设置定时器,把callback延迟执行
  11. setTimeout(() => {
  12. callback()
  13. }, interval)
  14. }

并行操作

先后(类似于同时)设置三个定时器,谁先到先执行谁 特点:三件事之间没有任何的关联/依赖

  1. delay(3000, () => {
  2. console.log('A')
  3. })
  4. delay(() => {
  5. console.log('B')
  6. })
  7. delay(2000, () => {
  8. console.log('C')
  9. })

—->’B’/‘C’/‘A’ 三件事都执行完毕需要 3000ms
特殊情况:都处理完毕后,做统一的一些事情

  1. const complete = function complete() {
  2. console.log('并行操作都处理完毕了')
  3. }
  4. let n = 0, num = 3
  5. delay(3000, () => {
  6. console.log('A')
  7. n++
  8. if (n >= num) complete()
  9. })
  10. delay(() => {
  11. console.log('B')
  12. n++
  13. if (n >= num) complete()
  14. })
  15. delay(2000, () => {
  16. console.log('C')
  17. n++
  18. if (n >= num) complete()
  19. })

串行操作

如果三件事有关联,例如:必须先处理A,A处理的结果会作为B处理的条件…也就是执行的顺序必须是 A->B->C 串行操作:必须在上一个处理完毕后,才能设置下一个定时器,因为三个的执行是有关联和依赖的

  1. delay(3000, () => {
  2. console.log('A')
  3. delay(() => {
  4. console.log('B')
  5. delay(2000, () => {
  6. console.log('C')
  7. })
  8. })
  9. })

“回调地狱”

  • 基于回调函数的方式来管理异步操作,在“并行”操作中没啥太大的问题,但是在“串行”操作中,会引发“在回调函数中,嵌套回调函数…”,这就是回调地狱!!
    • 基于一层层嵌套的方式,代码太“恶心”了,不利于开发和维护

      jQuery中的ajax

      需求:在项目中,有三个接口请求(串行请求),现在需要我们分别调用三个接口,完成数据的获取和绑定 接口1:/api/info -> {id:xxx,….} 接口2:/api/ranking?id=xxx -> {rank:27} 接口3:/api/prize?rank=27

在真实的工作中,我们用到的ajax请求“全部都是异步操作(虽然它支持同步的处理)”

  1. JQ$.ajax 基于回调函数的方式,来管理ajax异步请求的
  2. $.ajax({
  3. url:'',
  4. method:'GET',
  5. data:{
  6. // 传参信息
  7. },
  8. dataType:'json', //把从服务器获取的数据,转换为对象
  9. ...,
  10. success(result){
  11. // 请求成功的回调函数「result:从服务器获取的数据信息」
  12. },
  13. ...
  14. })

Ajax并行

同时发送多个异步请求,谁先从服务器获取数据,就先处理谁
特殊情况:都处理完毕后,做统一的一些事情

Ajax串行

多个请求之间有依赖,需要依次发送「上一个请求结束,才能发送下一个请求」

  1. $.ajax({
  2. url: '/api/info',
  3. success(result) {
  4. // 第一个请求成功
  5. // ...
  6. $.ajax({
  7. url: '/api/ranking?id=' + result.id,
  8. success(result2) {
  9. // 第二个请求成功
  10. // ...
  11. $.ajax({
  12. url: '/api/prize?rank=' + result2.rank,
  13. success(result3) {
  14. // 第三个请求成功
  15. // ...
  16. }
  17. })
  18. }
  19. })
  20. }
  21. })

基于 Promise 管理异步操作

  1. const delay = function delay(interval = 1000) {
  2. return new Promise(resolve => {
  3. setTimeout(() => {
  4. resolve()
  5. }, interval)
  6. })
  7. }

Promise并行:

  • 无需自己写计数器监测是否都成功,基于 Promise.all 就解决了

    1. let p1 = delay(3000).then(() => {
    2. console.log('A')
    3. })
    4. let p2 = delay().then(() => {
    5. console.log('B')
    6. })
    7. let p3 = delay(2000).then(() => {
    8. console.log('C')
    9. })
    10. Promise.all([p1, p2, p3]).then(() => {
    11. console.log('并行操作都处理完毕了')
    12. })

    Promise串行:

  • 有效避免回调地狱 ```javascript delay(3000) .then(() => { console.log(‘A’) return delay() }) .then(() => { console.log(‘B’) return delay(2000) }) .then(() => { console.log(‘C’) })

;(async function(){ await delay(3000) console.log(‘A’)

await delay() console.log(‘B’)

await delay(2000) console.log(‘C’) })()

  1. <a name="Trey5"></a>
  2. ### 简单了解axios
  3. > 平时项目中,我们可以使用 axios 插件来发送数据请求,相比较于 $.ajax,其不是基于 callback 回调函数的方式管理异步请求的,而是基于 Promise 来管理异步操作的!!
  4. > 需求:在项目中,有三个接口请求(串行请求),现在需要我们分别调用三个接口,完成数据的获取和绑定<br /> 接口1:/api/info -> {id:xxx,....}<br /> 接口2:/api/ranking?id=xxx -> {rank:27}<br /> 接口3:/api/prize?rank=27
  5. <a name="urSvF"></a>
  6. #### 串行
  7. ```javascript
  8. axios.get('/api/info')
  9. .then(result => {
  10. // 第一个请求成功 ...
  11. return axios.get(`/api/ranking?id=${result.id}`)
  12. })
  13. .then(result2 => {
  14. // 第二个请求成功 ...
  15. return axios.get(`/api/prize?rank=${result2.rank}`)
  16. })
  17. .then(result3 => {
  18. // 第三个请求成功 ...
  19. })

配合async await使用
  1. (async () => {
  2. let result = await axios.get('/api/info')
  3. // 第一个请求成功 ...
  4. result = await axios.get(`/api/ranking?id=${result.id}`)
  5. // 第二个请求成功 ...
  6. result = await axios.get(`/api/prize?rank=${result.rank}`)
  7. // 第三个请求成功 ...
  8. })()

并行

  1. axios.get('/api/list').then(() => {
  2. // ...
  3. })
  4. axios.get('/api/info').then(() => {
  5. // ...
  6. })
  7. axios.get('/api/test').then(() => {
  8. // ...
  9. })