首頁 > 軟體

兩個函數相互呼叫如何防止死迴圈

2023-03-29 06:00:40

兩個函數相互呼叫防止死迴圈

最近碰到了一個問題,就是兩個函數相互呼叫遭遇死迴圈的問題,想了半天終於想出了一個演演算法破解,姑且叫它熵遞減演演算法。

問題的抽象程式碼如下

/*
*  methodA 和 methodB 迴圈呼叫,是死迴圈
* */
function methodA() {
    console.log('A的事情');
    methodB();
}
function methodB() {
    console.log('B的事情');
    methodA();
}

不論呼叫哪個方法,都會產生死迴圈。

我想要的效果是:

如果觸發A方法時,也執行一下B方法,到此為止不再回圈下去,反之亦然。

因此,必須能判斷方法是主動發起的,還是被動的。

抽象程式碼如下:

/*
*  解決問題的關鍵在於,判斷方法是主動發起的,還是被動的
* */
function methodA() {
    console.log('A的事情');
    if('A是主動的'){
        methodB();
    }else{
        // 不再呼叫下去
    }
}
function methodB() {
    console.log('B的事情');
    if('B是主動的'){
        methodA();
    }else{
        // 不再呼叫下去
    }
}

解法,就是熵遞減演演算法,如下

/*
* 熵遞減演演算法
* */

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;
    }
}

熵遞減演演算法的說明:

給一個全域性變數,叫做總步數pairMethodStep ,初始值為2。任一個方法執行時,做完自己的事情後,把pairMethodStep減成1。然後,判斷此時的pairMethodStep,如果是1, 就呼叫另一個方法;如果是0了,就不再繼續呼叫了,而是把pairMethodStep恢復成2。

我們分析一下程式碼執行的過程。主動的方法執行前,pairMethodStep的值是2,它做完自己的事後,把pairMethodStep的值變成了1,緊跟著就會執行被動的方法;被動的方法執行前,pairMethodStep的值是1,被動的方法做完自己的事情後,把pairMethodStep的值減成了0,不會再呼叫另一個方法了(不會發生死迴圈了),而僅僅是把pairMethodStep還原成2。

目的達到。熵遞減演演算法,能完美地解決兩個函數相互呼叫的問題。

js函數互相呼叫碰到的問題

專案場景

兩個函數互相呼叫時

(當一個系統比較大時,尤其是涉及到一些複雜的演演算法時,很有可能會碰到死迴圈的情況發生,造成系統的CPU飆升)

        function a1() {
            console.log("a1");
            b1();
        }
        function b1() {
            console.log("b1");
            a1();
        }

問題描述

會進入死迴圈

原因分析

就類似for迴圈,或者遞迴函數如果沒有退出條件就會一直執行

解決方案

        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;
            }
        }

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com