Js开发_Vue 回调&异步常用总结


① 第一步:callback

1. 方法回调

<template>
  <div class="hello">
    <button type="button" @click="setCallBack()"> testCallback </button>
  </div>
</template>
<script>
export default {
  name: 'callback',
  data () {
    return {
      result: 0
    }
  },
  methods: { 
    setCallBack() { 
      this.init((res) => {
        console.log(res)
      })
    },
    init(callback) {
      setTimeout(() => {
        if(Math.random() <= 0.6) {
          callback(1)
        } else {
          callback(2)
        }
      }, 100)
    }
  }
}
</script>

2:回调地狱

<template>
  <div class="hello">
    <button type="button" @click="startCallback()"> test </button>
  </div>
</template>

<script>
export default {
  name: 'callback',
  data () {
    return {
      result: 0
    }
  },
  methods: { 
    startCallback(){
      setTimeout(()=>{
        console.log('callback 0.5秒',new Date());
        setTimeout(()=>{
          console.log('callback 0.4秒',new Date());
          setTimeout(()=>{
            console.log('callback 0.3秒',new Date());
            setTimeout(()=>{
              console.log('callback 0.2秒',new Date());
              setTimeout(()=>{
                console.log('callback 0.1秒',new Date());
              }, 100);
            }, 200);
          }, 300);
        }, 400);
      }, 500);
    }
  }
}
</script>

3. 回调地狱的改善

<template>
  <div class="hello">
    <button type="button" @click="startCallback()"> test </button>
  </div>
</template>

<script>
export default {
  name: 'callback',
  data () {
    return {
      result: 0
    }
  },
  methods: { 
    call1(next){
      setTimeout(()=>{
        console.log('callback 0.5秒',new Date());
        next();
      },500);
    },
    call2(next){
      setTimeout(()=>{
        console.log('callback 0.4秒',new Date());
        next();
      },400);
    },
    call3(next){
      setTimeout(()=>{
          console.log('callback 0.3秒',new Date());
          next();
      },300);
    },
    call4(next){
      setTimeout(()=>{
          console.log('callback 0.2秒',new Date());
          next();
      },200);
    },
    call5(){
      setTimeout(()=>{
        console.log('callback 0.1秒',new Date());
      },100);
    },
    startCallback(){
      this.call1(()=>{
        this.call2(()=>{
            this.call3(()=>{
                this.call4(()=>{
                    this.call5();
                });
            });
        });
      });
    }
  }
}
</script>

② 第二步 : Promise

Promise他将提供一种更加优雅的方法,让我们写回调函数。

Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。

这么说用Promise new出来的对象肯定就有then、catch方法

 

 

 

 

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点:

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。

     只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

简单来说,Promise 就是用同步的方式写异步的代码,用来解决回调问题

<template>
  <div class="hello">
    <button type="button" @click="startCallback()"> test </button>
  </div>
</template>

<script>
export default {
  name: 'callback',
  data () {
    return {
      result: 0
    }
  },
  methods: { 
    call1(){
      var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('callback 0.5秒',new Date());
            resolve();
        },500);
      });
      return p;
    },
    call2(){
      var p=new Promise((resolve,reject)=>{
          setTimeout(()=>{
              console.log('callback 0.4秒',new Date());
              resolve();
          },400);
      });
      return p;
    },
    call3(){
      var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
          console.log('callback 0.3秒',new Date());
          resolve();
        },300);
      });
      return p;
    },
    call4(){
      var p=new Promise((resolve,reject)=>{
          setTimeout(()=>{
            console.log('callback 0.2秒',new Date());
            resolve();
          },200);
      });
      return p;
    },
    call5(){
      var p=new Promise((resolve,reject)=>{
          setTimeout(()=>{
            console.log('callback 0.1秒',new Date());
            resolve();
          },100);
      });
      return p;
    },
    startCallback() {
      var self = this
      this.call1()
      .then(function(data){
        return self.call2();
      })
      .then(function(data){
          return self.call3();
      })
      .then(function(data){
          return self.call4();
      })
      .then(function(data){
          return self.call5();
      })
    }
  }
}
</script>

 

第三步: Async/await/Promise

Async/await的主要益处是可以避免回调地狱(callback hell且以最接近同步代码的方式编写异步代码。

1.【方法中等待异步】  

简单理解:async 是让方法变成异步 await是等待异步方法执行完毕。

<template>
  <div class="hello">
    <button type="button" @click="setPromise()"> test </button>
  </div>
</template>
<script>
export default { name: 'HelloWorld', data () { return { result: 0 } }, methods: { setPromise() { var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('ok'); // reject('error');  }, time); }) }; var start = async function (self) { try { console.log('start async'); self.result = await sleep(3000); // 这里得到了一个返回错误 console.log('async后:'+ self.result); // 收到 ‘ok’ } catch (err) { console.log(err); // 这里捕捉到错误 `error`  } }; start(this) console.log('async ago '+ this.result); // 收到 ‘ok’  } } } </script>

2. 【复数异步方法】

 复数异步方法顺序执行

<template>
  <div class="hello">
    <button type="button" @click="setPromise()"> test </button>
  </div>
</template>

<script>
export default { name: 'HelloWorld', data () { return { result: 0 } }, methods: { setPromise() { let initIndex = function(self) { Promise.resolve().then(function(){ console.log('step 1: start') return self.init() }).then(function(res) { console.log('step 2: ' + res) return self.getToken() }).then(function(token) { console.log('step 3: ' + token) return self.getServerData(1) }).then(function(data) { console.log('step 4: ' + data) return self.getServerData(2) }).then(function(data) { console.log('step 5: ' + data) console.log('finish') }) } initIndex(this) }, init() { return new Promise((resolve, reject) => { resolve('return true') }) }, getToken() { return new Promise((resolve, reject) => { resolve('return token') }) }, getServerData(data) { return new Promise((resolve, reject) => { resolve('return getServerData' + data) }) } } } </script>

3. 【复数异步方法】

 复数方法优先执行

<template>
  <div class="hello">
    <button type="button" @click="setPromise()"> test </button>
  </div>
</template>

<script>
export default { name: 'HelloWorld', data () { return { result: 0 } }, methods: { setPromise() { let $init = this.init() let $getToken = this.getToken() let $getServerData1 = this.getServerData(1) let $getServerData2 = this.getServerData(2) Promise.all([$init, $getToken, $getServerData1, $getServerData2]).then((values) => { console.log(values) console.log('finish') }); }, init() { return new Promise((resolve, reject) => { resolve('return true') }) }, getToken() { return new Promise((resolve, reject) => { resolve('return token') }) }, getServerData(data) { return new Promise((resolve, reject) => { resolve('return getServerData' + data) }) } } } </script>

4.【循环中等待异步】

<template>
  <div class="hello">
    <button type="button" @click="setAgvList()"> test </button>
    <ul  v-for="item in items">
      <li>{{item.count}}:{{item.name}}</li>
    </ul>
  </div>
</template>

<script>
export default { name: 'HelloWorld', data () { return { items: [] } }, methods :{ setAgvList() { const commonAsync = async() => { for (var count = 0; count < 5; count++) { var name = await this.getRobotByIndex(count) var status = { count: count, name: name } this.items.push(status) } console.log(this.items) } commonAsync() }, async getRobotByIndex (agvIndex) { return "hello world!" + agvIndex } } } </script>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM