最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中定時(shí)器的使用及頁(yè)面切換時(shí)定時(shí)器無(wú)法清除問(wèn)題的解決辦法

 更新時(shí)間:2023年02月07日 09:19:37   作者:coderZzb  
定時(shí)器相信大家應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于JS中定時(shí)器的使用及頁(yè)面切換時(shí)定時(shí)器無(wú)法清除問(wèn)題的解決辦法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、定時(shí)器的區(qū)別:

1、定時(shí)器分類(lèi):

JS有兩種定時(shí)器分別是setTimeout()setInterval(),這兩個(gè)區(qū)別就是setTimeout()是一次性的定時(shí)器,而setInterval()是循環(huán)的定時(shí)器。

(1)setTimeout()

只執(zhí)行一次,在指定的毫秒數(shù)之后,就會(huì)立即停止

(2)setInterval()

不管語(yǔ)句是否執(zhí)行完成,不管是否執(zhí)行錯(cuò)誤,到下一次指定的毫秒數(shù)后就會(huì)立即執(zhí)行

(3)舉例:

比如想調(diào)用一個(gè)接口,需要1s定時(shí)刷新一次,但是接口2s才返回?cái)?shù)據(jù),使用setInterval()的話就會(huì)出現(xiàn)問(wèn)題,在上次接口還沒(méi)有返回結(jié)果的情況下,又重新調(diào)用了接口,這樣交互效果很不好,影響性能;所以在開(kāi)發(fā)中,在遇到接口需要定時(shí)的情況,我都會(huì)使用setTimeout(),配合clearTimeout使用,需要注意的是:a. 不能把setTimeout寫(xiě)成死循環(huán); b. 注意清除定時(shí)器的情況;c. 頁(yè)面切換清除定時(shí)器的情況,這個(gè)是重點(diǎn),也是下面需要講到的問(wèn)題

2、setInterval()的使用場(chǎng)景:

(1)可以使用在動(dòng)畫(huà)效果上,比如閃爍效果

(2)其他不需要異步及調(diào)用接口的方法 都可以使用(個(gè)人的總結(jié),可能不太對(duì))

(3)如果想停止,可以使用clearInterval()或關(guān)閉窗口

3、setTimeout()的使用場(chǎng)景

(1)定時(shí)器執(zhí)行一次的情況下 可以使用,這種場(chǎng)景很少見(jiàn),這里就不舉例了

(2)調(diào)用的接口需要定時(shí)查詢(xún)的情況,這種場(chǎng)景很常見(jiàn),比如天氣查詢(xún),定時(shí)10秒刷新一次,在開(kāi)發(fā)中經(jīng)常用到

4、定時(shí)器遇到的問(wèn)題(以下是我在做項(xiàng)目中遇到的問(wèn)題及自己的一點(diǎn)想法)

(1)用setTimeout 實(shí)現(xiàn)定時(shí)查詢(xún) 一般用于執(zhí)行的方法中調(diào)用后臺(tái)接口的情況,等接口請(qǐng)求完后,再執(zhí)行下一次的接口調(diào)用; 使用setInterval的話,一般用于不調(diào)用后臺(tái)接口的情況

(2)要是用setInterval用來(lái)調(diào)用后端接口,可能會(huì)有問(wèn)題,比如定時(shí)2s刷新,接口可能會(huì)3s才返回接口,還沒(méi)等這次返回結(jié)果去刷新頁(yè)面,就又去重新查詢(xún)數(shù)據(jù)了,可能會(huì)造成數(shù)據(jù)混亂

(3)在使用setTimeout的時(shí)候,需要注意的問(wèn)題就是不要寫(xiě)成死循環(huán);再就是記得清除定時(shí)器,清除定時(shí)器用clearTimeout 方法

(4)在使用react的時(shí)候,會(huì)遇到路由切換的情況,有時(shí)候會(huì)出現(xiàn)定時(shí)器清除不掉的情況

比如在A頁(yè)面中是用了定時(shí)器setTimeout,但是沒(méi)有清除定時(shí)器,那么在訪問(wèn)B頁(yè)面的時(shí)候,A頁(yè)面的定時(shí)器還會(huì)執(zhí)行,請(qǐng)求的接口也仍然會(huì)繼續(xù)執(zhí)行,所以要清除一下,在A頁(yè)面切換到B頁(yè)面的時(shí)候,會(huì)執(zhí)行組件卸載的方法(componentWillUnmount),在該方法中調(diào)用清除定時(shí)器的方法(clearTimeout);

有時(shí)候可能會(huì)失敗,比如剛巧在執(zhí)行componentWillUnmount的時(shí)候,恰好代碼也執(zhí)行到定時(shí)器執(zhí)行的調(diào)用后臺(tái)接口的方法中了,還在請(qǐng)求接口,在請(qǐng)求成功到執(zhí)行下一次定時(shí)器的時(shí)候,恰好componentWillUnmount方法把之前的定時(shí)器清除了,這樣雖然清除了上次的定時(shí)器,但是那個(gè)方法中又再次使用了定時(shí)器,這樣的話,就會(huì)造成清不掉的問(wèn)題(這個(gè)大家可能會(huì)遇到這個(gè)問(wèn)題)

(5)上述問(wèn)題的React示例代碼及運(yùn)行截圖

測(cè)試頁(yè)面1的代碼:

import React, { Component } from 'react';
import { getRealtimeValueByCodeList } from '../../SVGManagementNew/services/index'; // 引用的查詢(xún)實(shí)時(shí)值的接口

export default class TestPage1 extends Component {
    constructor(props) {
        super(props);

        this.state = {
            refreshTime: 500 // 500毫秒
        };

        this.timeout = null;
    }

    componentDidMount() {
        this.getRealValueFn();
    }

    componentWillUnmount() {
        clearTimeout(this.timeout);
    }

    // 獲取實(shí)時(shí)值
    getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FCALT2DPU2A')
            .then((res) => {
                console.log(res);

                this.timeout = setTimeout(() => {
                    console.log('page1定時(shí)查詢(xún)');

                    this.getRealValueFn();
                }, this.state.refreshTime);
            })
            .catch((e) => {
                console.log(e);
            });
    };

    render() {
        return <div>TestPage1</div>;
    }
}

測(cè)試頁(yè)面2的代碼:

import React, { Component } from ‘react’;
import { getRealtimeValueByCodeList } from ‘…/…/SVGManagementNew/services/index’; // 引用的查詢(xún)實(shí)時(shí)值的接口

export default class TestPage2 extends Component {
    constructor(props) {
        super(props);

        this.state = {
            refreshTime: 500 // 500毫秒
        };

        this.timeout = null;
    }

    componentDidMount() {
        this.getRealValueFn();
    }

    componentWillUnmount() {
        clearTimeout(this.timeout);
    }

    // 獲取實(shí)時(shí)值
    getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FDRJ4_IDCS00116_R2')
            .then((res) => {
                console.log(res);

                this.timeout = setTimeout(() => {
                    console.log('page2定時(shí)查詢(xún)');

                    this.getRealValueFn();
                }, this.state.refreshTime);
            })
            .catch((e) => {
                console.log(e);
            });
    };

    render() {
        return <div>TestPage1</div>;
    }
}

測(cè)試頁(yè)面3的代碼

import React, { useState, useRef, useEffect } from ‘react’;
import PropTypes from ‘prop-types’;
import { getRealtimeValueByCodeList } from ‘…/…/SVGManagementNew/services/index’; // 引用的查詢(xún)實(shí)時(shí)值的接口

function TestPage3(props) {
    const [refreshTime, setRefreshTime] = useState(500);
    const timeout = useRef();

    const getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FDDM1_TEST_CTM')
            .then((res) => {
                console.log(res);
                timeout.current = setTimeout(() => {
                    console.log('page3定時(shí)查詢(xún)');
                    getRealValueFn();
                }, refreshTime);
            })
            .catch((e) => {
                console.log(e);
            });
    };

    useEffect(() => {
        getRealValueFn();

        return () => {
            clearTimeout(timeout.current);
        };
    }, []);

    return <div>TestPage3</div>;
}

TestPage3.propTypes = {};

export default TestPage3;

配置三個(gè)路由,然后來(lái)回切換這三個(gè)頁(yè)面,就會(huì)出現(xiàn)定時(shí)器清除不掉的情況,三個(gè)頁(yè)面的定時(shí)器就會(huì)一直在刷新,這樣就會(huì)造成資源上的浪費(fèi)及占用內(nèi)容,要是頁(yè)面很多、定時(shí)刷新的接口很多、接口很耗費(fèi)資源的話,那么這種情況就會(huì)影響整個(gè)程序的運(yùn)行,有可能還會(huì)引起系統(tǒng)崩潰

上圖就是我在來(lái)回切換三個(gè)測(cè)試頁(yè)面的時(shí)候,出現(xiàn)上述說(shuō)的問(wèn)題,可以自己把上述的代碼試驗(yàn)下

5、解決上述遇到的第四個(gè)問(wèn)題,即使用setTimeout頁(yè)面切換時(shí)定時(shí)器無(wú)法清除的問(wèn)題

a. 解決思路:

(1)從問(wèn)題的根本出發(fā),問(wèn)題的根本就是在頁(yè)面切換的時(shí)候,因?yàn)槎〞r(shí)器緩存的問(wèn)題,在切換到其他的頁(yè)面后,無(wú)法清除,還會(huì)繼續(xù)在緩存中繼續(xù)執(zhí)行;

(2)那么從這個(gè)思路上去想,在從A頁(yè)面(有定時(shí)器)跳轉(zhuǎn)到B頁(yè)面的時(shí)候,A頁(yè)面的定時(shí)器沒(méi)有清除掉,那么是否是可以在A頁(yè)面的定時(shí)器方法那定義個(gè)變量,然后在全局定義個(gè)變量,然后通過(guò)這兩個(gè)變量來(lái)判斷是否不執(zhí)行定時(shí)器呢;

(3)根據(jù)這個(gè)思路去想,那么是否可以根據(jù)路由去判斷,比如在訪問(wèn)到A頁(yè)面的時(shí)候,在A頁(yè)面的代碼中記錄下A頁(yè)面的路由到一個(gè)參數(shù)中(該參數(shù)在定時(shí)器執(zhí)行的時(shí)候,是一塊保存到緩存中的,在切換路由的時(shí)候,并不會(huì)清除,這個(gè)是一個(gè)存在緩存中的變量),然后在路由切換的時(shí)候,監(jiān)聽(tīng)路由的變化,記錄最新訪問(wèn)的路由,保存到window對(duì)象中(因?yàn)閣indow是全局的,在任何地方都可以使用);

(4)那么這兩個(gè)變量都有了,然后根據(jù)這兩個(gè)變量判斷,如果相等的話,那說(shuō)明正好是這個(gè)頁(yè)面,可以執(zhí)行定時(shí)器,如果不相等,那么當(dāng)前訪問(wèn)的頁(yè)面不是這個(gè)頁(yè)面,那么定時(shí)器就不執(zhí)行了

b. 實(shí)現(xiàn)步驟:

(1)在外部定義一個(gè)監(jiān)控方法,可以在main.js中 也可以在index.js中,也可以在路由切換中的文件中,把下面的代碼加入進(jìn)去,注意的是location的獲取,有的js文件中可能獲取不到

	window.onhashchange = () => {
        console.log('監(jiān)聽(tīng)路由變化');
        // 獲取當(dāng)前變化的路由
        window.curPathName = this.props.location.pathname;
    };

下圖是我自己添加的位置:

(2)在使用定時(shí)器的文件中,設(shè)置每個(gè)文件使用時(shí)訪問(wèn)的路由地址

(3)判斷是否加載定時(shí)器

c.完整的示例代碼,可以正常清除定時(shí)器的

測(cè)試頁(yè)面1的代碼:

import React, { Component } from 'react';
import { getRealtimeValueByCodeList } from '../../SVGManagementNew/services/index'; // 引用的查詢(xún)實(shí)時(shí)值的接口

export default class TestPage1 extends Component {
    constructor(props) {
        super(props);

        this.state = {
            refreshTime: 500, // 500毫秒
            curPageUrl: '' // 當(dāng)前頁(yè)面的訪問(wèn)地址
        };

        this.timeout = null;
    }

    componentDidMount() {
        const urlParams = window.location.href;
        this.setState({
            curPageUrl: urlParams
        });

        this.getRealValueFn();
    }

    componentWillUnmount() {
        clearTimeout(this.timeout);
    }

    // 獲取實(shí)時(shí)值
    getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FCALT2DPU2A')
            .then((res) => {
                console.log(res);
                if (this.state.curPageUrl.indexOf(window.curPathName) >= 0 || !window.curPathName) {
                    this.timeout = setTimeout(() => {
                        console.log('page1定時(shí)查詢(xún)');

                        this.getRealValueFn();
                    }, this.state.refreshTime);
                }
            })
            .catch((e) => {
                console.log(e);
            });
    };

    render() {
        return <div>TestPage1</div>;
    }
}

測(cè)試頁(yè)面2的代碼:

import React, { Component } from 'react';
import { getRealtimeValueByCodeList } from '../../SVGManagementNew/services/index'; // 引用的查詢(xún)實(shí)時(shí)值的接口

export default class TestPage2 extends Component {
    constructor(props) {
        super(props);

        this.state = {
            refreshTime: 500, // 500毫秒
            curPageUrl: '' // 當(dāng)前頁(yè)面的訪問(wèn)地址
        };

        this.timeout = null;
    }

    componentDidMount() {
        const urlParams = window.location.href;
        this.setState({
            curPageUrl: urlParams
        });

        this.getRealValueFn();
    }

    componentWillUnmount() {
        clearTimeout(this.timeout);
    }

    // 獲取實(shí)時(shí)值
    getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FDRJ4_IDCS00116_R2')
            .then((res) => {
                console.log(res);
                if (this.state.curPageUrl.indexOf(window.curPathName) >= 0 || !window.curPathName) {
                    this.timeout = setTimeout(() => {
                        console.log('page2定時(shí)查詢(xún)');

                        this.getRealValueFn();
                    }, this.state.refreshTime);
                }
            })
            .catch((e) => {
                console.log(e);
            });
    };

    render() {
        return <div>TestPage1</div>;
    }
}

測(cè)試頁(yè)面3的代碼:

import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { getRealtimeValueByCodeList } from '../../SVGManagementNew/services/index'; // 引用的查詢(xún)實(shí)時(shí)值的接口

function TestPage3(props) {
    const [refreshTime, setRefreshTime] = useState(500);
    const [curPageUrl, setCurPageUrl] = useState(window.location.href);
    const timeout = useRef();

    const getRealValueFn = () => {
        getRealtimeValueByCodeList('CF159FDDM1_TEST_CTM')
            .then((res) => {
                console.log(res);
                if (this.state.curPageUrl.indexOf(window.curPathName) >= 0 || !window.curPathName) {
                    timeout.current = setTimeout(() => {
                        console.log('page3定時(shí)查詢(xún)');
                        getRealValueFn();
                    }, refreshTime);
                }
            })
            .catch((e) => {
                console.log(e);
            });
    };

    useEffect(() => {
        console.log(curPageUrl);

        getRealValueFn();

        return () => {
            clearTimeout(timeout.current);
        };
    }, []);

    return <div>TestPage3</div>;
}

TestPage3.propTypes = {};

export default TestPage3;

總結(jié):

到此這篇關(guān)于JS中定時(shí)器的使用及頁(yè)面切換時(shí)定時(shí)器無(wú)法清除問(wèn)題的解決辦法的文章就介紹到這了,更多相關(guān)JS定時(shí)器無(wú)法清除解決內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

尼玛县| 肃南| 西安市| 黄浦区| 长兴县| 济阳县| 延津县| 樟树市| 隆回县| 绥滨县| 西乌| 阿图什市| 正蓝旗| 广平县| 潼关县| 宜章县| 盘山县| 曲靖市| 祁门县| 旬邑县| 顺昌县| 霸州市| 隆回县| 牙克石市| 望谟县| 永春县| 长武县| 泰来县| 大方县| 望都县| 夏邑县| 府谷县| 黄浦区| 怀集县| 合阳县| 辽宁省| 无棣县| 琼海市| 镇康县| 库车县| 阳西县|