-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
节流,防抖,wait-promise 与异步 Timer #15
Labels
util
工具
Comments
await this.asyncPollingPayResult()
// 开始轮询支付状态
async asyncPollingPayResult() {
let startFlag = 1
let timer = setInterval(() => {
startFlag++
if (startFlag > 15 || this.isPaySuccess === true) {
clearInterval(timer)
} else {
this.pollingReauestPayResult()
}
}, 2000)
await wait.before(30000).until(() => {
if (this.isPaySuccess === true) {
// 清空购物车
this.clearNewOrder()
return true
} else {
return false
}
}).then(() => {
// 30秒内收到成功结果
}).catch(() => {
// 30秒内未收到成功的结果或收到失败的结果
this.showMessage('服务器忙,请联系前台')
})
}
// 微信付款后轮询支付状态是否成功
pollingReauestPayResult() {
wepy.request({
url: pollingPayResultApi,
method: 'POST',
header: {
'Content-Type': 'Application/json;charset=UTF-8'
},
data: {}
}).then((response) => {
console.log(response)
this.checkPayResult(response.data)
}).catch((error) => {
wepy.showToast({
title: '服务器忙!',
})
return false
})
}
// 判断轮询结果
checkPayResult(data) {
if (data.return_code === undefined ||
data.return_code === 'FAIL') {
console.log('支付成功后拉取状态:失败:', data)
return false
} else if (data.return_code === 'SUCCESS') {
this.methods.updateSettleOrder(data.order)
this.isPaySuccess = true
this.$apply()
}
} |
throttle 节流
function throttle(callback, wait, context = this) {
let timeout = null
let callbackArgs = null
const later = () => {
callback.apply(context, callbackArgs)
timeout = null
}
return function() {
if (!timeout) {
callbackArgs = arguments
timeout = setTimeout(later, wait)
}
}
}
/**
* Normal event
* event | | |
* time ----------------
* callback | | |
*
* Call search at most once per 300ms while keydown
* keydown | | | |
* time -----------------
* search | |
* |300| |300|
*/
/** usage
const handleKeydown = throttle((e) => {
console.log(e.target.value)
}, 300)
input.addEventListener('keydown', handleKeydown)
*/ |
debounce 防抖
function debounce(callback, wait, context = this) {
let timeout = null
let callbackArgs = null
const later = () => callback.apply(context, callbackArgs)
return function() {
callbackArgs = arguments
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
}
/**
* Normal event
* event | | |
* time ----------------
* callback | | |
*
* Call log only when it's been 100ms since the last sroll
* scroll | | |
* time ----------------
* callback | |
* |100| |100|
*/
/* usage
const handleScroll = debounce((e) => {
console.log('Window scrolled.')
}, 100)
window.addEventListener('scroll', handleScroll)
*/ |
es6-promise-debounce |
带触发边界的 throttle 节流/**
* 频率控制 返回函数连续调用时,func 执行频率限定为 次 / wait
*
* @param {function} func 传入函数
* @param {number} wait 表示时间窗口的间隔
* @param {object} options 如果想忽略开始边界上的调用,传入{leading: false}。
* 如果想忽略结尾边界上的调用,传入{trailing: false}
* @return {function} 返回客户调用函数
*/
_.throttle = function(func, wait, options) {
let context, args, result
let timeout = null
// 上次执行时间点
let previous = 0
if (!options) options = {}
// 延迟执行函数
let later = function() {
// 若设定了开始边界不执行选项,上次执行时间始终为0
previous = options.leading === false ? 0 : new Date().getDate()
timeout = null
result = func.apply(context, args)
if (!timeout) context = args = null
};
return function() {
let now = new Date().getDate()
// 首次执行时,如果设定了开始边界不执行选项,将上次执行时间设定为当前时间。
if (!previous && options.leading === false) previous = now
// 延迟执行时间间隔
let remaining = wait - (now - previous)
context = this
args = arguments
// 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口
// remaining大于时间窗口wait,表示客户端系统时间被调整过
if (remaining <= 0 || remaining > wait) {
clearTimeout(timeout)
timeout = null
previous = now
result = func.apply(context, args)
if (!timeout) context = args = null
//如果延迟执行不存在,且没有设定结尾边界不执行选项
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining)
}
return result
}
} |
带触发边界的 debounce 防抖/**
* 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
*
* @param {function} func 传入函数
* @param {number} wait 表示时间窗口的间隔
* @param {boolean} immediate 设置为ture时,调用触发于开始边界而不是结束边界
* @return {function} 返回客户调用函数
*/
const _.debounce = function(func, wait, immediate) {
let timeout, args, context, timestamp, result
let later = function() {
// 据上一次触发时间间隔
let last = new Date().getDate() - timestamp
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function() {
context = this
args = arguments
timestamp = new Date().getDate()
let callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
} |
防抖 装饰器工厂 @debounceexport function debounce(timeout) {
const instanceMap = new Map(); // 创建一个Map的数据结构,将实例化对象作为key
return function (target, key, descriptor) {
return Object.assign({}, descriptor, {
value: function value() {
// 清除延时器
clearTimeout(instanceMap.get(this));
// 设置延时器
instanceMap.set(this, setTimeout(() => {
// 调用该方法
descriptor.value.apply(this, arguments);
// 将延时器设置为 null
instanceMap.set(this, null);
}, timeout));
}
})
}
}
class Test {
@debounce(600)
onNext() {
console.log('click')
}
} |
节流 装饰器工厂 @Throttle
export function throttle(time) {
//let flag = false
const instanceMap = new Map(); // 创建一个Map的数据结构,将实例化对象作为key
return function (target, key, descriptor) {
return Object.assign({}, descriptor, {
value: function value() {
//if (flag) return
if (instanceMap.get(this)) return
descriptor.value.apply(this, arguments);
instanceMap.set(this, true)
//flag = true
setTimeout(() => {
//flag = false
instanceMap.set(this, null)
}, time)
}
})
}
}
class Test {
@throttle(600)
onNext() {
console.log('click')
}
} |
函数节流 Throttleexport const throttle = (func, wait) => {
const instanceMap = new Map();
return function() {
if (instanceMap.get(this)) return;
func.apply(this, arguments);
instanceMap.set(this, true);
setTimeout(() => {
instanceMap.set(this, null);
}, wait);
};
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
throttle 和 debounce
https://github.com/akira-cn/wait-promise
https://www.h5jun.com/post/wait-promise.html
The text was updated successfully, but these errors were encountered: