文章目录
- 思路一 每秒执行
- 思路二 直接用定时器,但是不每秒
- 思路三 es9 异步迭代
- 异步迭代
- 例子1 直接使用
- 例子2 async await
- 例子3 * yield
- 异步遍历器 --》要想用for await of 必须遍历这个
- 简化 for await of
- 解决1秒出现第一个结果,再过2秒出现第二个,再过3秒出现第三个的问题
今天菜鸟碰见了一个需求
菜鸟一看,感觉有点懵逼,就是突然感觉不是很好实现,如果每一秒去调一次感觉浪费内存,如果用定时器就会产生递归(注:菜鸟一开始以为递归不好写,所以产生了第三种写法!)。
思路一 每秒执行
二维码第一次打开的时候,倒计时30秒,如果这个时候点击了,时间重置,否则走到0后,收回二维码。收回二维码后再计时10秒,如果有点击按钮,计时取消,开启30秒倒计时。如果没有点击按钮,计时10秒后打开二维码,然后开启30秒倒计时。
这个就是利用变量控制是否展示或者隐藏!每一秒都需要使用定时器去获取变量的值,感觉比较浪费内存。
思路二 直接用定时器,但是不每秒
代码:
<template>
<div>
<button @click="showQRCode">点击微信捐步</button>
<div v-show="displayQRCode" class="qr-code">
<img :src="qrCodeUrl" alt="QR Code" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
qrCodeUrl: require("@/assets/imgs/bg.png"),
displayQRCode: false,
timeoutId: null,
};
},
methods: {
showQRCode() {
clearTimeout(this.timeoutId);
this.displayQRCode = true;
this.timeoutId = setTimeout(() => {
this.displayQRCode = false;
this.hideQRCode();
}, 5000); // 30秒后自动收回
},
hideQRCode() {
this.timeoutId = setTimeout(() => {
this.showQRCode();
}, 3000); // 10秒后再次展示
},
},
mounted() {
this.hideQRCode(); // 初始状态下隐藏二维码,10秒后再次展示
},
beforeDestroy() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
}
},
};
</script>
<style>
.qr-code {
position: fixed;
left: 0;
right: 0;
margin: auto;
width: 200px;
height: 200px;
z-index: 999;
}
</style>
核心代码:
showQRCode() {
clearTimeout(this.timeoutId); // 一定要清除,不然多点几次就相互影响了
this.displayQRCode = true;
this.timeoutId = setTimeout(() => {
this.displayQRCode = false;
this.hideQRCode();
}, 5000); // 30秒后自动收回
},
hideQRCode() {
this.timeoutId = setTimeout(() => {
this.showQRCode();
}, 3000); // 10秒后再次展示
},
思路三 es9 异步迭代
<template>
<div class="home">
<div class="fruitBox">
<p class="aaa" @click="showFun">点击出现</p>
</div>
<div class="rankBox"></div>
<div
class="qcBox animate__animated"
:class="qcBoxshow ? 'animate__zoomIn' : 'animate__zoomOut'"
>
<div class="qctop">
<img class="qcborder" src="~@/assets/imgs/qc_border.png" />
<img class="qc" src="~@/assets/imgs/0516.png" />
</div>
<div class="qctxt">
<p>微信捐步</p>
<p>参加积分兑换</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
qcBoxshow: true,
qcBoxshowtimer: null,
qcBoxshowFun: null,
};
},
created() {
const _this = this;
// es9 --> 异步迭代
async function* gen() {
yield _this.setShow(30);
yield _this.setShow(10);
}
_this.qcBoxshowFun = async function test() {
let g = gen();
let arr = [g.next(), g.next()];
for await (let i of arr) {
console.log(i);
}
_this.qcBoxshowFun();
};
this.qcBoxshowFun();
},
methods: {
setShow(time) {
return new Promise((resolve) => {
this.qcBoxshowtimer = setTimeout(() => {
this.qcBoxshow = !this.qcBoxshow;
resolve(this.qcBoxshow);
}, time * 1000);
});
},
showFun() {
this.qcBoxshow = true;
clearTimeout(this.qcBoxshowtimer);
this.qcBoxshowtimer = null;
this.qcBoxshowFun();
},
},
};
</script>
<style lang="scss" scoped>
.home {
width: 100%;
height: 100%;
position: relative;
}
.fruitBox {
.aaa {
font-size: 100px;
color: white;
}
}
.rankBox {
position: absolute;
left: 80px;
bottom: 65px;
width: 692px;
height: 1403px;
background-image: url("~@/assets/imgs/rank_border.png");
background-size: 100% 100%;
}
.qcBox {
position: absolute;
right: 300px;
bottom: 890px;
.qctop {
width: 412px;
height: 418px;
position: relative;
}
.qcborder {
width: 418px;
height: 418px;
}
.qc {
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-44%, -50%);
}
.qctxt {
font-size: 40px;
line-height: 60px;
text-align: center;
p {
color: white;
margin: 0;
text-shadow: 0px 0px 19px #41a5c7;
}
}
}
</style>
异步迭代主要是解决几个异步请求,要按照顺序依次执行,使用then会让代码陷入回调地狱的的问题。放在这里其实不是很合适!
异步迭代
期望结果:1秒出现第一个结果,再过2秒出现第二个,再过3秒出现第三个!
例子1 直接使用
结果
三个promise对象(X)
例子2 async await
结果
注:
其实for循环已经执行完毕,只是因为内部被await搞成了异步,所以会出现该效果!await并行执行!
例子3 * yield
结果
111
222
注:
同步遍历器遍历promise对象时,感觉不太好!没有链式调用!
异步遍历器 --》要想用for await of 必须遍历这个
async 结合 * yield
第一种写法:
结果
第二种写法:
结果
简化 for await of
解决1秒出现第一个结果,再过2秒出现第二个,再过3秒出现第三个的问题
结果
注:等待结果调用后,再执行整个代码块!