vue3 实战使用hook,实现sleep功能、有条件的wait

968 阅读1分钟

sleep实现

sleep功能比较简单,就是使用setTimeout,可是setTimeout写一个回调并不好看

期望类似这样的语法

//code1
sleep(300)
//code2

由于js是异步的,所以直接使用sleep是不行的,可以使用await语法

代码示例:

<template>
<div>
<a-button @click="onClick">点击</a-button>
</div>

</template>


<script>

async function useSleep(timeout = 300){
  return new Promise(resolve => {
    setTimeout(()=>{
      resolve();
    },timeout)
  })
}

export default {
  name: "test-1",
  setup(){
    return {
      useSleep,
    }
  },
  methods:{
    async onClick(){
      console.log('1111',new Date().getTime());
      await this.useSleep();
      console.log('2222',new Date().getTime());
    }
  }
}
</script>

<style scoped>

</style>

输出截图

image.png

等待事件完成

还有一个情况是需要等待直到某个事件完成,才算完成

例如等待地图初始化完成,才渲染marker

<template>
<div>
<a-map @ok="mapOk"></a-map>
</div>

</template>


<script>


export function useWaitUntilOk(){
  let isOk = false;
  return {
    setUntilOk(){
      isOk = true;
    },
    /**
     *
     * @param timeout 超时
     * @param interval 检查间隔
     * @param condition 检查条件
     * @return {Promise<unknown>}
     */
    waitUntilOk(timeout = 0,interval = 50,condition = null){
      condition = condition || function (){};
      let start_time = new Date().getTime();
      return new Promise((resolve,reject) => {
        if(timeout > 0 && new Date().getTime() - start_time > timeout){
          reject();
        }
        let interval_i = setInterval(()=>{
          if(isOk || condition()){
            clearInterval(interval_i);
            resolve();
          }
        },interval);
      })
    },
  }
}
export default {
  name: "test-1",
  setup(){
    const {setUntilOk,waitUntilOk} = useWaitUntilOk();
    return {
      setUntilOk,
      waitUntilOk,
    }
  },
  created() {
    //api请求数据
    api().then(()=>{
      this.renderData();
    })
  },
  methods:{
    async renderData(){
        await this.waitUntilOk();
        //等待地图初始化完成后才有mapObj对象,渲染marker
        new this.mapObj.Marker();
    },
    mapOk(mapObj){
      this.mapObj = mapObj;
      //地图初始化完成
      this.setUntilOk();
    }
  }
}
</script>

<style scoped>

</style>

可以看到示例代码,地图初始化是异步的,api请求也是异步的,api请求后渲染marker,但是需要等待地图初始化完成

总结

这里我们从业务情况提炼出了2个hook,useSleepuseWaitUntilOk方便以后使用

hook 就是业务逻辑的提取和重用