中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

高職院校高水平專業(yè)建設(shè)網(wǎng)站花都網(wǎng)站建設(shè)公司

高職院校高水平專業(yè)建設(shè)網(wǎng)站,花都網(wǎng)站建設(shè)公司,萊蕪做網(wǎng)站公司,山西建設(shè)局網(wǎng)站Debounce debounce 原意消除抖動(dòng),對(duì)于事件觸發(fā)頻繁的場景,只有最后由程序控制的事件是有效的。 防抖函數(shù),我們需要做的是在一件事觸發(fā)的時(shí)候設(shè)置一個(gè)定時(shí)器使事件延遲發(fā)生,在定時(shí)器期間事件再次觸發(fā)的話則清除重置定時(shí)器&#xff…

Debounce

debounce 原意消除抖動(dòng),對(duì)于事件觸發(fā)頻繁的場景,只有最后由程序控制的事件是有效的。

防抖函數(shù),我們需要做的是在一件事觸發(fā)的時(shí)候設(shè)置一個(gè)定時(shí)器使事件延遲發(fā)生,在定時(shí)器期間事件再次觸發(fā)的話則清除重置定時(shí)器,直到定時(shí)器到時(shí)仍不被清除,事件才真正發(fā)生。

const debounce = (fun, delay) => {let timer;return (...params) => {if (timer) {clearTimeout(timer);}timer = setTimeout(() => {fun(...params);}, delay);};
};

如果事件發(fā)生使一個(gè)變量頻繁變化,那么使用debounce可以降低修改次數(shù)。通過傳入修改函數(shù),獲得一個(gè)新的修改函數(shù)來使用。

如果是class組件,新函數(shù)可以掛載到組件this上,但是函數(shù)式組件局部變量每次render都會(huì)創(chuàng)建,debounce失去作用,這時(shí)需要通過useRef來保存成員函數(shù)(下文throttle通過useRef保存函數(shù)),是不夠便捷的,就有了將debounce做成一個(gè)hook的必要。

function useDebounceHook(value, delay) {const [debounceValue, setDebounceValue] = useState(value);useEffect(() => {let timer = setTimeout(() => setDebounceValue(value), delay);return () => clearTimeout(timer);}, [value, delay]);return debounceValue;
}

在函數(shù)式組件中,可以將目標(biāo)變量通過useDebounceHook轉(zhuǎn)化一次,只有在滿足delay的延遲之后,才會(huì)觸發(fā),在delay期間的觸發(fā)都會(huì)重置計(jì)時(shí)。

配合useEffect,在debounce value改變之后才會(huì)做出一些動(dòng)作。下面的text這個(gè)state頻繁變化,但是依賴的是debounceText,所以引發(fā)的useEffect回調(diào)函數(shù)卻是在指定延遲之后才會(huì)觸發(fā)。

const [text,setText]=useState('');
const debounceText = useDebounceHook(text, 2000);
useEffect(() => {// ...console.info("change", debounceText);
}, [debounceText]);function onChange(evt){setText(evt.target.value)
}

上面一個(gè)搜索框,輸入完成1秒(指定延遲)后才觸發(fā)搜索請(qǐng)求,已經(jīng)達(dá)到了防抖的目的。


Throttle

throttle 原意節(jié)流閥,對(duì)于事件頻繁觸發(fā)的場景,采用的另一種降頻策略,一個(gè)時(shí)間段內(nèi)只能觸發(fā)一次。

節(jié)流函數(shù)相對(duì)于防抖函數(shù)用在事件觸發(fā)更為頻繁的場景上,滑動(dòng)事件,滾動(dòng)事件,動(dòng)畫上。

看一下一個(gè)常規(guī)的節(jié)流函數(shù) (ES6):

function throttleES6(fn, duration) {let flag = true;let funtimer;return function () {if (flag) {flag = false;setTimeout(() => {flag = true;}, duration);fn(...arguments);// fn.call(this, ...arguments);// fn.apply(this, arguments); // 運(yùn)行時(shí)這里的 this 為 App組件,函數(shù)在 App Component 中運(yùn)行} else {clearTimeout(funtimer);funtimer = setTimeout(() => {fn.apply(this, arguments);}, duration);}};
}

參考 前端進(jìn)階面試題詳細(xì)解答

(使用...arguments和 call 方法調(diào)用展開參數(shù)及apply 傳入argument的效果是一樣的)

擴(kuò)展:在ES6之前,沒有箭頭函數(shù),需要手動(dòng)保留閉包函數(shù)中的this和參數(shù)再傳入定時(shí)器中的函數(shù)調(diào)用:

所以,常見的ES5版本的節(jié)流函數(shù):

function throttleES5(fn, duration) {let flag = true;let funtimer;return function () {let context = this,args = arguments;if (flag) {flag = false;setTimeout(function () {flag = true;}, duration);fn.apply(context, args); // 暫存上一級(jí)函數(shù)的 this 和 arguments} else {clearTimeout(funtimer);funtimer = setTimeout(function () {fn.apply(context, args);}, duration);}};
}

如何將節(jié)流函數(shù)也做成一個(gè)自定義Hooks呢?上面的防抖的Hook其實(shí)是對(duì)一個(gè)變量進(jìn)行防抖的,從一個(gè)不間斷頻繁變化的變量得到一個(gè)按照規(guī)則(停止變化delay時(shí)間后)才能變化的變量。我們對(duì)一個(gè)變量的變化進(jìn)行節(jié)流控制,也就是從一個(gè)不間斷頻繁變化的變量指定duration期間只能變化一次(結(jié)束后也會(huì)變化)的變量。

throttle對(duì)應(yīng)的Hook實(shí)現(xiàn):

(標(biāo)志能否調(diào)用值變化的函數(shù)的flag變量在常規(guī)函數(shù)中通過閉包環(huán)境來保存,在Hook中通過useRef保存)

function useThrottleValue(value, duration) {const [throttleValue, setThrottleValue] = useState(value);let Local = useRef({ flag: true }).current;useEffect(() => {let timer;if (Local.flag) {Local.flag = false;setThrottleValue(value);setTimeout(() => (Local.flag = true), duration);} else {timer = setTimeout(() => setThrottleValue(value), duration);}return () => clearTimeout(timer);}, [value, duration, Local]);return throttleValue;
}

對(duì)應(yīng)的在手勢(shì)滑動(dòng)中的使用:

export default function App() {const [yvalue, setYValue] = useState(0);const throttleValue = useThrottleValue(yvalue, 1000);useEffect(() => {console.info("change", throttleValue);}, [throttleValue]);function onMoving(event, tag) {const touchY = event.touches[0].pageY;setYValue(touchY);}return (<divonTouchMove={onMoving}style={{ width: 200, height: 200, backgroundColor: "#a00" }}    />);
}

這樣以來,手勢(shì)的yvalue值一直變化,但是因?yàn)槭褂玫氖?code>throttleValue,引發(fā)的useEffect回調(diào)函數(shù)已經(jīng)符合規(guī)則被節(jié)流,每秒只能執(zhí)行一次,停止變化一秒后最后執(zhí)行一次。

對(duì)值還是對(duì)函數(shù)控制

上面的Hooks封裝其實(shí)對(duì)值進(jìn)行控制的,第一個(gè)防抖的例子中,輸入的text跟隨輸入的內(nèi)容不斷的更新state,但是因?yàn)?code>useEffect是依賴的防抖之后的值,這個(gè)useEffect的執(zhí)行是符合防抖之后的規(guī)則的。

可以將這個(gè)防抖規(guī)則提前嗎? 提前到更新state就是符合防抖規(guī)則的,也就是只有指定延遲之后才能將新的value進(jìn)行setState,當(dāng)然是可行的。但是這里搜索框的例子并不好,對(duì)值變化之后發(fā)起的請(qǐng)求可以進(jìn)行節(jié)流,但是因?yàn)樗阉骺蛐枰獙?shí)時(shí)呈現(xiàn)輸入的內(nèi)容,就需要實(shí)時(shí)的text值。

對(duì)手勢(shì)觸摸,滑動(dòng)進(jìn)行節(jié)流的例子就比較好了,可以通過設(shè)置duration來控制頻率,給手勢(shì)值的setState降頻,每秒只能setState一次:

export default function App() {const [yvalue, setYValue] = useState(0);const Local = useRef({ newMoving: throttleFun(setYValue, 1000) }).current;useEffect(() => {console.info("change", yvalue);}, [yvalue]);function onMoving(event, tag) {const touchY = event.touches[0].pageY;Local.newMoving(touchY);}return (<divonTouchMove={onMoving}style={{ width: 200, height: 200, backgroundColor: "#a00" }}    />);
}//常規(guī)節(jié)流函數(shù)
function throttleFun(fn, duration) {let flag = true;let funtimer;return function () {if (flag) {flag = false;setTimeout(() => (flag = true), duration);fn(...arguments);} else {clearTimeout(funtimer);funtimer = setTimeout(() => fn.apply(this, arguments), duration);}};
}

這里就是對(duì)函數(shù)進(jìn)行控制了,控制函數(shù)setYValue的頻率,將setYValue函數(shù)傳入節(jié)流函數(shù),得到一個(gè)新函數(shù),手勢(shì)事件中使用新函數(shù),那么setYValue的調(diào)用就符合了節(jié)流規(guī)則。如果這里依然是對(duì)手勢(shì)值節(jié)流的話,其實(shí)會(huì)有很多的不必要的setYValue執(zhí)行,這里對(duì)setYValue函數(shù)進(jìn)行節(jié)流控制顯然更好。

需要注意的是,得到的新函數(shù)需要通過useRef作為“實(shí)例變量”暫存,否則會(huì)因?yàn)楹瘮?shù)組件每次render執(zhí)行重新創(chuàng)建。

http://www.risenshineclean.com/news/49462.html

相關(guān)文章:

  • wordpress 優(yōu)秀插件seo設(shè)置是什么
  • 哪個(gè)網(wǎng)站做外單出口好個(gè)人模板建站
  • wordpress rss錯(cuò)誤四川seo快速排名
  • 關(guān)于網(wǎng)站建設(shè)公司大全上海app定制開發(fā)公司
  • 北京天海網(wǎng)站建設(shè)公司黃頁網(wǎng)站推廣app咋做廣告
  • 做網(wǎng)站的公司找客戶衡陽百度推廣
  • 深圳H5網(wǎng)站開發(fā)南寧seo專員
  • 上海網(wǎng)站建設(shè)網(wǎng)頁制作邢臺(tái)備案查詢網(wǎng)
  • 贛州市開發(fā)小程序搜索優(yōu)化整站優(yōu)化
  • 網(wǎng)站備案信息查詢百度seo營銷推廣多少錢
  • 彩票投注網(wǎng)站怎樣做安徽網(wǎng)站建設(shè)優(yōu)化推廣
  • 做百度手機(jī)網(wǎng)站優(yōu)化成都seo網(wǎng)絡(luò)優(yōu)化公司
  • 阜陽網(wǎng)站建設(shè)工作室營銷圖片素材
  • 扁平風(fēng)網(wǎng)站哪家培訓(xùn)機(jī)構(gòu)學(xué)校好
  • 高校邦營銷型網(wǎng)站建設(shè)答案semifinal
  • 找人做網(wǎng)站注意哪些女教師遭網(wǎng)課入侵視頻大全播放
  • 微信網(wǎng)站開發(fā)簡單百度如何注冊(cè)公司網(wǎng)站
  • 權(quán)大師的網(wǎng)站是哪個(gè)公司做的指數(shù)基金是什么意思
  • 西安網(wǎng)站建設(shè)那家強(qiáng)深圳網(wǎng)絡(luò)營銷渠道
  • 鄭州網(wǎng)站制作公司名單外貿(mào)新手怎樣用谷歌找客戶
  • 企業(yè)網(wǎng)站備案在哪個(gè)部門seo教學(xué)
  • seo外貿(mào)網(wǎng)站建設(shè)百度下載安裝2021最新版
  • 上海做響應(yīng)式網(wǎng)站的公司江西seo
  • 那個(gè)網(wǎng)站做室內(nèi)比較好的網(wǎng)站流量排行
  • 拉新推廣變現(xiàn)app寧德seo推廣
  • 網(wǎng)站建站卡頓怎么辦流量查詢網(wǎng)站
  • 深圳網(wǎng)站建設(shè)易佰訊寧波seo排名外包
  • 烏魯木齊經(jīng)濟(jì)開發(fā)區(qū)建設(shè)局網(wǎng)站如何創(chuàng)建自己的網(wǎng)址
  • 有個(gè)藍(lán)色章魚做標(biāo)志的網(wǎng)站seo和sem的聯(lián)系
  • 蘇寧易購網(wǎng)站建設(shè)的目的競價(jià)關(guān)鍵詞排名軟件