兩個函數(shù)相互調(diào)用如何防止死循環(huán)
兩個函數(shù)相互調(diào)用防止死循環(huán)
最近碰到了一個問題,就是兩個函數(shù)相互調(diào)用遭遇死循環(huán)的問題,想了半天終于想出了一個算法破解,姑且叫它熵遞減算法。
問題的抽象代碼如下
/* * ?methodA 和 methodB 循環(huán)調(diào)用,是死循環(huán) * */ function methodA() { ? ? console.log('A的事情'); ? ? methodB(); } function methodB() { ? ? console.log('B的事情'); ? ? methodA(); }
不論調(diào)用哪個方法,都會產(chǎn)生死循環(huán)。
我想要的效果是:
如果觸發(fā)A方法時,也執(zhí)行一下B方法,到此為止不再循環(huán)下去,反之亦然。
因此,必須能判斷方法是主動發(fā)起的,還是被動的。
抽象代碼如下:
/* * ?解決問題的關(guān)鍵在于,判斷方法是主動發(fā)起的,還是被動的 * */ function methodA() { ? ? console.log('A的事情'); ? ? if('A是主動的'){ ? ? ? ? methodB(); ? ? }else{ ?? ??? ?// 不再調(diào)用下去 ?? ?} } function methodB() { ? ? console.log('B的事情'); ? ? if('B是主動的'){ ? ? ? ? methodA(); ? ? }else{ ?? ??? ?// 不再調(diào)用下去 ?? ?} }
解法,就是熵遞減算法,如下
/* * 熵遞減算法 * */ var pairMethodStep = 2; function methodA() { ? ? pairMethodStep --; ? ? console.log('A的事情'); ? ? if(pairMethodStep === 1){ ? ? ? ? methodB(); ? ? }else{ ? ? ? ? pairMethodStep = 2; ? ? } } function methodB() { ? ? pairMethodStep --; ? ? console.log('B的事情'); ? ? if(pairMethodStep === 1){ ? ? ? ? methodA(); ? ? }else{ ? ? ? ? pairMethodStep = 2; ? ? } }
熵遞減算法的說明:
給一個全局變量,叫做總步數(shù)pairMethodStep ,初始值為2。任一個方法執(zhí)行時,做完自己的事情后,把pairMethodStep減成1。然后,判斷此時的pairMethodStep,如果是1, 就調(diào)用另一個方法;如果是0了,就不再繼續(xù)調(diào)用了,而是把pairMethodStep恢復(fù)成2。
我們分析一下代碼執(zhí)行的過程。主動的方法執(zhí)行前,pairMethodStep的值是2,它做完自己的事后,把pairMethodStep的值變成了1,緊跟著就會執(zhí)行被動的方法;被動的方法執(zhí)行前,pairMethodStep的值是1,被動的方法做完自己的事情后,把pairMethodStep的值減成了0,不會再調(diào)用另一個方法了(不會發(fā)生死循環(huán)了),而僅僅是把pairMethodStep還原成2。
目的達到。熵遞減算法,能完美地解決兩個函數(shù)相互調(diào)用的問題。
js函數(shù)互相調(diào)用碰到的問題
項目場景
兩個函數(shù)互相調(diào)用時
(當一個系統(tǒng)比較大時,尤其是涉及到一些復(fù)雜的算法時,很有可能會碰到死循環(huán)的情況發(fā)生,造成系統(tǒng)的CPU飆升)
? ? ? ? function a1() { ? ? ? ? ? ? console.log("a1"); ? ? ? ? ? ? b1(); ? ? ? ? } ? ? ? ? function b1() { ? ? ? ? ? ? console.log("b1"); ? ? ? ? ? ? a1(); ? ? ? ? }
問題描述
會進入死循環(huán)
原因分析
就類似for循環(huán),或者遞歸函數(shù)如果沒有退出條件就會一直執(zhí)行
解決方案
? ? ? ? let flagNum = 1; ? ? ? ? ? function a1() { ? ? ? ? ? ? flagNum--; ? ? ? ? ? ? console.log("a1"); ? ? ? ? ? ? if (flagNum === 0) { ? ? ? ? ? ? ? ? b1(); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? flagNum = 1; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? function b1() { ? ? ? ? ? ? flagNum--; ? ? ? ? ? ? console.log("b1"); ? ? ? ? ? ? if (flagNum === 0) { ? ? ? ? ? ? ? ? a1(); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? flagNum = 1; ? ? ? ? ? ? } ? ? ? ? }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于uniapp微信小程序左上角返回按鈕的監(jiān)聽詳解
uniapp是一個支持多端的技術(shù),因此它是兼容性比較強的,而且速度也很快,下面這篇文章主要給大家介紹了關(guān)于uniapp微信小程序左上角返回按鈕監(jiān)聽的相關(guān)資料,需要的朋友可以參考下2022-04-04僅用[]()+!等符號就足以實現(xiàn)幾乎任意Javascript代碼
僅用一些符號就足以實現(xiàn)幾乎任意Javascript代碼的方法,比較怪異,對于特殊需要可能用得到。2010-03-03