Canvas 在 JavaScript 完成执行之前不会更新

Canvas is not updating until JavaScript has finished executing

使用 HTML5 canvas 对 PostFix 堆栈实现进行中缀。期望的输出是,canvas 中的元素框必须输出每个字符 1 秒,然后逐渐消失。而问题是 canvas 中的元素框在代码执行完成后更新,这导致 canvas 元素框中的所有字符重叠,然后在 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);
        }
    }

}

他们是否要分别更新每个角色的 canvas?

一个选项是 elementVisualize 到 return 一个 Promise 在矩形被清除时解析,await Promise 在每个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() 一个项目,然后在动画之后再次调用自身,如果有一些字符保留在数组中。