关于Promise封装异步递归轮询(vue2-demo)

633 阅读1分钟

简要说明:利用promise 做状态管理,使用递归去调用接口,使用定时器去限制递归的频率,在内部限制递归的次数,销毁组件时中断递归轮询

<template>
  <div class="home">
    <h1>home</h1>
  </div>
</template>

<script>
export default {
  name: "HomeView",

  data() {
    return {
      esc: false, // 组件销毁时,中断递归轮询
    };
  },
  mounted() {
    this.getData().then((data)=>{
    console.log(data)
    )
  },
  beforeDestroy() {
    this.esc = true;
  },
  methods: {
    // 获取数据
    getData() {
      return new Promise((resolve, reject) => {
        // 运行一个模型  得到一个id  , 然后去轮询另外一个接口,拿到返回值
        this.Api1()
          .then((res) => {
            if (res.data) {
              const index = 1;
              // 递归轮询一个接口 去拿返回值
              this.setTimeoutAnalysis(res.data, index)
                .then((result) => {
                  console.log("轮询结束", result);
                  resolve(result);
                })
                .catch(() => {
                  console.log("轮询出错");
                  reject();
                });
            } else {
              reject();
            }
          })
          .catch(() => {
            reject();
          });
      });
    },
    // 递归轮询
    setTimeoutAnalysis(modelId, index) {
      const _this = this;
      return new Promise((resolve, reject) => {
        // 定时器轮询 请求
        console.log(`第 ${index} 次轮询`);
        this.Api2(modelId).then((result) => {
          console.log("result", result);
          const runStatus = result?.code;

          if (runStatus === "error") {
            reject();
          }

          if (runStatus === "finish") {
            resolve(result);
          }

          if (index >= 15) {
            reject();
          }
          if (runStatus === "running" && index < 15) {
            console.log("正在轮询");
            console.log("esc", this.esc);
            const currentIndex = index + 1;
            if (!this.esc) {
              setTimeout(() => {
                resolve(_this.setTimeoutAnalysis(modelId, currentIndex));
              }, 3000);
            } else {
              console.log("中断递归");

              reject();
            }
          }
        });
      });
    },

    // ----------------- 华丽分割线
    // 模拟异步接口1
    Api1() {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({
            data: "dahjsdgjahgsdjhasgdhj",
          });
        }, 3000);
      });
    },
    // 模拟异步接口2
    Api2() {
      return new Promise((resolve) => {
        const index = Math.random() * 100;
        if (index < 90) {
          resolve({
            code: "running",
          });
        }
        if (index >= 90) {
          resolve({
            code: "finish",
            data: {},
          });
        }
      });
    },
  },
};
</script>