首页 > 解决方案 > 在 JavaScript 完成执行之前,Canvas 不会更新

问题描述

使用 HTML5 画布对 PostFix 堆栈实现进行中缀。所需的输出是,画布中的元素框必须输出每个字符 1 秒,然后逐渐消失。问题是代码执行完成后画布中的元素框正在更新,这导致画布元素框中的所有字符重叠,然后在 1 秒后淡出。

请看下面的代码:

function convert(e){         // when convert button click
    var x = document.getElementById('infix').value;
    var stack = new Stack();
    stack.postFix(x);
}

function elementVisualize(ele){
    var eleVis = canvas.getContext('2d');

    eleVis.fillText(ele,150,150);
    console.log(ele);

    setTimeout(function(){
        eleVis.clearRect(100,80,148,148);
    }, 1000);
}

postFix(exp){           // Stack.postFix function
    for(var i = 0; i < exp.length ; i++){
        var c = exp[i];
        if((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z')){
            elementVisualize(c);
        }
    }

}

他们无论如何都要分别更新每个角色的画布吗?

标签: javascripthtmlcanvassingle-threaded

解决方案


一种选择是 forelementVisualize返回Promise在清除矩形时解析的 a ,并在循环awaitPromise每次迭代中返回for

function elementVisualize(ele){
    var eleVis = canvas.getContext('2d');

    eleVis.fillText(ele,150,150);

    return new Promise((resolve) => {
        setTimeout(function(){ 
            eleVis.clearRect(100,80,148,148);
            resolve();
        }, 1000);
    });
}

async postFix(exp){           // Stack.postFix function
     for(var i = 0; i < exp.length ; i++){
     var c = exp[i];
     if((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z')){
           await elementVisualize(c);
     }
}

如果postFix还可以在所有动画完成之前再次调用该方法,并且您希望它等待上一个postFix调用的动画完成,您可能会考虑一个持久的排序队列,postFix将项目( 的字符exp)推送到该队列,并有elementVisualize shift()一个如果数组中还有一些字符,则该数组中的项,然后在动画之后再次调用自身。


推荐阅读