/**
* 步骤并合修饰器,避免公共步骤并发进行
* 将公共步骤单例化:若步骤未在进行,则发起该步骤;若步骤正在进行,则监听并使用其执行结果,而不是重新发起该步骤
* @param target
* @param name
* @param descriptor
*/
function mergingStep(target, name, descriptor) {
let oriFunc = descriptor.value;
let runningInstance = null;
descriptor.value = function (...args) {
//若步骤正在进行,则监听并返回其执行结果
if (runningInstance)
return runningInstance;
let res = oriFunc.apply(this, args);
runningInstance = res;
// 添加一定时器,若长时间未响应,清除该步骤正在执行状态
let timeout = setTimeout(()=>{
runningInstance = null;
timeout = null;
},5000)
if (res instanceof Promise) {
runningInstance.then(function () {
runningInstance = null;
}).catch(function () {
runningInstance = null;
});
//操作结束 清空定时器
clearTimeout(timeout)
timeout = null
}else {
runningInstance = null;
clearTimeout(timeout)
timeout = null
}
return runningInstance;
}
}
使用示例
/**
* 避免并发调用,在上一次操作步骤完成前, 忽略重复执行
* 如:用户连续多次点击提交表单,只响应一次,而不是重复执行
* 使用示例:
* import {mergingStep} from '../decorators';
* methods: {
* @mergingStep //避免并发,点击提交后,在接口返回之前无视后续点击
* async submitOrder() {
* let order = await $wz.httpApi.payFood(this.getFoodOrder(this))
* if(order && order.status == 0 && order.data.orderSn){
* wx.navigateTo({url: '/pages/pay?orderSn='+order.data.orderSn+"&url=/pages/canteen/ordersuc"})
* }
* }
*/
参考网友