Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归函数的Webworker_Javascript_Recursion_Web Worker - Fatal编程技术网

Javascript 递归函数的Webworker

Javascript 递归函数的Webworker,javascript,recursion,web-worker,Javascript,Recursion,Web Worker,我已经从一篇旧帖子()中找到了一些答案 现在我接管这个暗示这个问题的小代码。这段小代码使用内联webworkers,因为我使用了一个递归函数来计算最佳点击率(这是“计算机”点击率)。如果我不使用webworker,而且深度太高,游戏就会挂在浏览器上 代码源代码可在[此链接][1]上获得 我想得到一个工作代码。事实上,我已经接近解决方案,因为已经修复了几个bug(例如,在webworker中包含不同的函数,使其在不调用外部函数的情况下进行计算。如果我没有包含所有必要的函数,webworker将无法

我已经从一篇旧帖子()中找到了一些答案

现在我接管这个暗示这个问题的小代码。这段小代码使用内联webworkers,因为我使用了一个递归函数来计算最佳点击率(这是“计算机”点击率)。如果我不使用webworker,而且深度太高,游戏就会挂在浏览器上

代码源代码可在[此链接][1]上获得

我想得到一个工作代码。事实上,我已经接近解决方案,因为已经修复了几个bug(例如,在webworker中包含不同的函数,使其在不调用外部函数的情况下进行计算。如果我没有包含所有必要的函数,webworker将无法工作,因为它有自己的作用域

因此,我想获得调试当前版本的帮助

游戏可在[此链接][2]上下载 我只对“计算机对播放器”模式感兴趣(黑色开始播放)。在下面,你可以找到我调用递归函数时的部分

使用这个递归函数完成计算后,我想返回表示当前游戏地图的对象(黑色/白色圆圈的位置)

为了返回对象或建议命中的坐标(这里是主函数),我执行了以下代码:

// 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 }
            console.log('here5');
        }
        firstWorker.postMessage([HitTemp, HitTemp.playerCurrent, maxNodes]);
    } ).then( ( { result } ) => {
        //let [ a, b ] = result.coordPlayable;
        let [ a, b ] = HitTemp.coordPlayable;
        console.log('result3 : ', result);
        console.log('here3 : ', a, b);
    } );

  // HERE I TRY TO USE a and b in exploreHitLine function
  // who needs the variables a and b BUT I DON'T KNOW
  // IF a AND b ARE KNOWN HERE FROM CODE ABOVE

  for (k = 0; k < 8; k++) {
   exploreHitLine(HitCurrent, a, b, k, 'drawing');
  }
//调用递归函数并获得最终(a,b)结果
新承诺(解决=>{
让HitTemp=JSON.parse(JSON.stringify(HitCurrent));
让firstWorker=newworker(workerScript);
firstWorker.onmessage=函数(事件){
解析(event.data);//{result:XXX}
console.log('here5');
}
firstWorker.postMessage([HitTemp,HitTemp.playerCurrent,maxNodes]);
})。然后({result})=>{
//设[a,b]=result.coordPlayable;
设[a,b]=HitTemp.coordPlayable;
log('result3:',result);
console.log('here3:',a,b);
} );
//在这里,我尝试在exploreHitLine函数中使用a和b
//谁需要变量a和b,但我不知道
//如果从上面的代码中知道a和b
对于(k=0;k<8;k++){
探索性地契线(当前、a、b、k,‘图纸’);
}
在递归函数下面(在内联webworker部分内):

window.onload=function(){
//内联webworker版本
workerScript=URL.createObjectURL(新Blob([`
“严格使用”;
...
...
//内联webworker所需的所有其他变量和函数
...
...
...
函数negaMax(HitCurrent、colorCurrent、depth){
//指数
变量i,j,k;
//评价
var arrayTemp,evalFinal,e;
//将当前颜色设置为当前颜色
HitCurrent.playerCurrent=彩色电流;
//arrayCurrent阵列的深度复制
arrayTemp=JSON.parse(JSON.stringify(HitCurrent.arrayCurrent));
//如果深度等于0
如果(深度==0)
返回评估(当前);
//开始评估
evalFinal=-无穷大;
//计算所有可播放的点击,并检查是否可播放点击
if(computeHit(HitCurrent,'playable')){
//浏览所有可能的点击
对于(i=0;i<8;i++)
对于(j=0;j<8;j++)
if(HitCurrent.ArrayPlayible[i][j]=“可播放”){
对于(k=0;k<8;k++){
//从(i,j)开始探索方向为“k”的直线
exploreehitline(当前,i,j,k,'图纸');
}
//递归调用
e=-negaMax(JSON.parse(JSON.stringify(HitCurrent)),((JSON.stringify(HitCurrent.playerCurrent)==JSON.stringify(playerBlack))?playerWhite:playerBlack),depth-1);
如果(e>evalFinal){
HitCurrent.coordPlayable=[i,j];
evalFinal=e;
}
if(e==-无穷大){
HitCurrent.coordPlayable=[i,j];
}
//还原阵列当前阵列
HitCurrent.arrayCurrent=JSON.parse(JSON.stringify(arrayTemp));
}
//完成双循环后,清除可播放的命中
清除命中(“可播放”,当前命中率);
}
console.log('here2:',evalFinal);
返回评估结果;
}
onmessage=函数(事件){
设params=event.data;
//postMessage({result:recursiveFunction(HitCurrent,HitCurrent.playerCurrent,maxNodes)});
postMessage({result:negaMax(…params)});
};
`],{type:“纯文本”});
main();
}
我希望通过递归函数返回计算值的坐标“a”和“b”,但它似乎什么也不返回

我不知道如何接收对象
HitTemp
对象,或者更直接地获取
a
b
建议的坐标


如果您不理解我在这个算法中的问题,请随时询问我更多的精确性。

您介绍的代码有两个问题:

问题#1:假设
postMessage
传递了一个引用,但它将其序列化/反序列化。 当您在主js中使用
postMessage
时,您将传递HitTemp对象,稍后,在WebWorker中,您假设如果设置该对象的属性,原始对象也将被修改。我指的是以下代码:

firstWorker.postMessage([
    HitTemp // <-- here you are sending the object to the WebWorker
, HitTemp.playerCurrent, maxNodes]);

workerScript = URL.createObjectURL( new Blob( [ `
// ...
    if (e > evalFinal) {
        HitCurrent.coordPlayable = [i,j]; // <-- here you access the object
        evalFinal = e;
    }
//...
解决方案 要解决第一个问题,您需要返回
HitCurrent
的值(其中包含您可能最感兴趣的
coordPlayable
)从WebWorker返回
postMessage
。对于第二个问题,只需使用
中的
a
b
变量移动
For
循环的最后一个
。然后()
firstWorker.postMessage([
    HitTemp // <-- here you are sending the object to the WebWorker
, HitTemp.playerCurrent, maxNodes]);

workerScript = URL.createObjectURL( new Blob( [ `
// ...
    if (e > evalFinal) {
        HitCurrent.coordPlayable = [i,j]; // <-- here you access the object
        evalFinal = e;
    }
//...
//...
} ).then( ( { result } ) => {
    let [ a, b ] = //here you define a and b
} );

// a and b are no longer in scope here
for (k = 0; k < 8; k++) {
    exploreHitLine(HitCurrent, a, b, k, 'drawing');
}
new Promise( resolve => {
    let HitTemp = JSON.parse(JSON.stringify(HitCurrent));
    let firstWorker = new Worker( workerScript );
    firstWorker.onmessage = function ( event ) {
        resolve( event.data );
        console.log('here5');
    }
    firstWorker.postMessage([HitTemp, HitTemp.playerCurrent, maxNodes]);
} ).then( ( { result } ) => {
    var HitResult = result.HitResult;
    let [ a, b ] = HitResult.coordPlayable; // <-- get values from result
    console.log('result3 : ', result.eval);
    console.log('here3 : ', a, b);

    //move for loop inside the callback
    for (k = 0; k < 8; k++) {
        exploreHitLine(HitCurrent, a, b, k, 'drawing');
    }
} );
window.onload = function() {

// Inline webworker version
workerScript = URL.createObjectURL( new Blob( [ `
"use strict";

// ...
function negaMax(HitCurrent, colorCurrent, depth) {
    // Indices
    var i, j, k;
    // Evaluation
    var arrayTemp, evalFinal, 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
    evalFinal = -infinity;
    // Compute all playable hits and check if playable hits
    if (computeHit(HitCurrent, 'playable')) {
        // 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 = -negaMax(JSON.parse(JSON.stringify(HitCurrent)).eval, ((JSON.stringify(HitCurrent.playerCurrent) == JSON.stringify(playerBlack)) ? playerWhite : playerBlack), depth-1); //since negaMax returns an object, don't forget to access the value in the recursive call

                    if (e > evalFinal) {
                        HitCurrent.coordPlayable = [i,j];
                        evalFinal = e;
                    }
                    if (e == -infinity) {
                        HitCurrent.coordPlayable = [i,j];
                    }
                    // Restore arrayCurrent array
                    HitCurrent.arrayCurrent = JSON.parse(JSON.stringify(arrayTemp));
                }
        // Clean playable hits once double loop is done
        cleanHits('playable', HitCurrent);
    }
    console.log('here2 :', evalFinal);
    return {eval: evalFinal, HitResult: HitCurrent }; //<-- send the additional HitCurrent as a result here
}
onmessage = function ( event ) {
    let params = event.data;
    postMessage( { result: negaMax( ...params ) } );
};
` ], { type: "plain/text" } ) );
main();
}