我有一个使用递归函数和Javascript的第一个版本,它可以产生预期的结果。在工作版本下面:

// Call the recursive function and get final (a,b) results
var HitTemp = JSON.parse(JSON.stringify(HitCurrent));
var result= recursiveFunction(HitTemp, HitTemp.playerCurrent, maxNodes);
var a = HitTemp.coordPlayable[0];
var b = HitTemp.coordPlayable[1];

// Recursive function
function recursiveFunction(HitCurrent, colorCurrent, depth) {
 // Indices
 var i, j, k;
 // Evaluation
 var arrayTemp, eval, e;
 // Set current color to HitCurrent
 HitCurrent.playerCurrent = colorCurrent;
 // Deep copy of arrayCurrent array
 arrayTemp = JSON.parse(JSON.stringify(HitCurrent.arrayCurrent));
 // If depth equal to 0
 if (depth == 0)
  return evaluation(HitCurrent);
 // Starting evaluation
 eval = -infinity;
 // Browse all possible hits
 for (i = 0; i < 8; i++)
  for (j = 0; j < 8; j++) {
   if (HitCurrent.arrayPlayable[i][j] == 'playable') {
    for (k = 0; k < 8; k++) {
     // Explore line started from (i,j) with direction "k"
     exploreHitLine(HitCurrent, i, j, k, 'drawing');
    }
    // Recursive call
    e = recursiveFunction(JSON.parse(JSON.stringify(HitCurrent)), ((JSON.stringify(HitCurrent.playerCurrent) == JSON.stringify(playerBlack)) ? playerWhite : playerBlack), depth-1);
    if (e > eval) {
     HitCurrent.coordPlayable = [i,j];
     eval = e;
    }
   }
   // Restore arrayCurrent array
   HitCurrent.arrayCurrent = JSON.parse(JSON.stringify(arrayTemp));
   }
 return eval;
}


由此,我想使用“内联” WebWorkers将递归专用于WebWorker,并避免在浏览器中挂起进程。

我试图遵循this linkthis other link

我不知道是否必须将对象postmessage或值HitCurrent“ cc”到主线程中:通过使用WebWorker,我在eval指令(在终端案例),并为下一个递归调用传递了objet return参数。

如果有人可以通过使用内联Webworker(或使用Webworker的经典方式)提供一些线索来重现此原始算法。

最佳答案

内联Webworker示例:

作为您的代码,没有function evaluationfunction exploreHitLine
在使用以下代码之前,必须将它们插入code

{
    let workerScript = URL.createObjectURL( new Blob( [ `
    "use strict";
    // Recursive function
    function recursiveFunction( HitCurrent, colorCurrent, depth ) {
        // Indices
        var i, j, k;
        // Evaluation
        var arrayTemp, eval, e;
        // Set current color to HitCurrent
        HitCurrent.playerCurrent = colorCurrent;
        // Deep copy of arrayCurrent array
        arrayTemp = JSON.parse(JSON.stringify(HitCurrent.arrayCurrent));
        // If depth equal to 0
        if ( depth === 0 ) return evaluation(HitCurrent);
        // Starting evaluation
        eval = -infinity;
        // Browse all possible hits
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                if (HitCurrent.arrayPlayable[i][j] === 'playable') {
                    for (k = 0; k < 8; k++) {
                        // Explore line started from (i,j) with direction "k"
                        exploreHitLine(HitCurrent, i, j, k, 'drawing');
                    }
                    // Recursive call
                    e = recursiveFunction(JSON.parse(JSON.stringify(HitCurrent)), ((JSON.stringify(HitCurrent.playerCurrent) == JSON.stringify(playerBlack)) ? playerWhite : playerBlack), depth-1);
                    if (e > eval) {
                        HitCurrent.coordPlayable = [i,j];
                        eval = e;
                    }
                }
                // Restore arrayCurrent array
                HitCurrent.arrayCurrent = JSON.parse(JSON.stringify(arrayTemp));
            }
        }
        return eval;
    }
    onmessage = function ( event ) {
        let params = event.data;
        postMessage( { result: recursiveFunction( ...params ) } );
    }
        ` ], { type: "plain/text" } ) );


    // Call the recursive function and get final (a,b) results
    new Promise( resolve => {
        let HitTemp = JSON.parse(JSON.stringify(HitCurrent));
        let firstWorker = new Worker( workerScript );
        firstWorker.onmessage = function ( event ) {
            resolve( event.data ); //{ result: XXX }
        }
        firstWorker.postMessage( HitTemp, HitTemp.playerCurrent, maxNodes );
    } ).then( ( { result } ) => {
        let [ a, b ] = result.coordPlayable;
        console.log( result );
    } );
}


此外,以下是内联WebWorker的工作方式:



{
    let workerScript = URL.createObjectURL( new Blob( [ `
    "use strict";
    onmessage = function ( event ) {
        let sum = 0, count = event.data;
        for ( let i = 0; i < count**count; i++ ) {
            sum += i;
        }
        postMessage( { result: sum, count } );
    }
    ` ], { type: "plain/text" } ) );
    let firstWorker = new Worker( workerScript );
    let firstAlive = setTimeout( () => {
        firstWorker.terminate();
        console.log( "terminated" );
    }, 3000 );
    firstWorker.onmessage = function ( event ) {
        clearTimeout( firstAlive );
        console.log( event.data );
    }
    firstWorker.postMessage( 10 );

    let secondWorker = new Worker( workerScript );
    let secondAlive = setTimeout( () => {
        secondWorker.terminate();
        console.log( "terminated" );
    }, 3000 );
    secondWorker.onmessage = function ( event ) {
        clearTimeout( secondAlive );
        console.log( event.data );
    }
    secondWorker.postMessage( 5 );

}





更新1。



{
    // Inline webworker version
    let workerScript = URL.createObjectURL( new Blob( [ `
    "use strict";
    // Recursive function
    function recursiveFunction( HitCurrent, colorCurrent, depth ) {
        // Indices
        var i, j, k;
        // Evaluation
        var arrayTemp, evaluated, e;
        // Set current color to HitCurrent
        HitCurrent.playerCurrent = colorCurrent;
        // Deep copy of arrayCurrent array
        arrayTemp = JSON.parse(JSON.stringify(HitCurrent.arrayCurrent));
        // If depth equal to 0
        if (depth == 0)
        return evaluation(HitCurrent);
        // Starting evaluation
        evaluated = -infinity;
        // Browse all possible hits
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                if (HitCurrent.arrayPlayable[i][j] == 'playable') {
                    for (k = 0; k < 8; k++) {
                        // Explore line started from (i,j) with direction "k"
                        exploreHitLine(HitCurrent, i, j, k, 'drawing');
                    }
                    // Recursive call
                    e = recursiveFunction(JSON.parse(JSON.stringify(HitCurrent)), ((JSON.stringify(HitCurrent.playerCurrent) == JSON.stringify(playerBlack)) ? playerWhite : playerBlack), depth-1);
                    if ( e > evaluated ) {
                        HitCurrent.coordPlayable = [i,j];
                        evaluated = e;
                    }
                    if (e == -infinity) { HitCurrent.coordPlayable = [ i, j ]; }
                    // Restore arrayCurrent array
                    HitCurrent.arrayCurrent = JSON.parse(JSON.stringify(arrayTemp));
                }
            }
        }
        return evaluated;
    }

    onmessage = function ( event ) {
        let params = event.data;
        //postMessage( { result: recursiveFunction(  HitCurrent, HitCurrent.playerCurrent, maxNodes ) } );
        postMessage( { result: recursiveFunction( ...params ) } );
    };
    ` ], { type: "plain/text" } ) );


   // Call the recursive function and get final (a,b) results
    new Promise( resolve => {
        let HitTemp = JSON.parse(JSON.stringify(HitCurrent));
        let firstWorker = new Worker( workerScript );
        firstWorker.onmessage = function ( event ) {
            resolve( event.data ); //{ result: XXX }
        }
        firstWorker.postMessage( [ HitTemp, HitTemp.playerCurrent, maxNodes ] );
    } ).then( ( { result } ) => {
        let [ a, b ] = result.coordPlayable;
        console.log( result );
    } );
}





我的错误的解释:


在“严格模式”下,不可能将“ eval”用作变量的名称。


=>

来自:eval

到:evaluated


Worker.postMessage( aMessage, Transferrable ),在这种情况下,您无需使用第二个参数。


=>

来自:firstWorker.postMessage( HitTemp, HitTemp.playerCurrent, maxNodes );

到:firstWorker.postMessage( [ HitTemp, HitTemp.playerCurrent, maxNodes ] );

https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage


继续到2,将参数传递给recursiveFunction是固定的。

关于javascript - 尝试实现内联Webworker的递归功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49867753/

10-11 23:34