javascript - 如果可能的话,我真的不应该使用 setInterval 和 setTimeout 吗?

标签 javascript settimeout setinterval requestanimationframe

我正在学习用 JavaScript 编写代码。我正在用一些定时鼠标动画编程。我正要添加一些绘制鼠标路径的代码。

这将是一个接受mousemove事件的东西,每次鼠标移动都会在Canvas上绘制一条新的线路径。随着时间的推移,这条道路将变得更加透明,直到它消失。当然,新路径总是不透明的,因此会有连续的移动。

我找到了一种方法,只需请求一个动画框架即可做到这一点。基本上每次发生新的 mousemove 事件时,我都会将该鼠标路径坐标添加到一个名为 mousePathArray 的对象数组中。该对象将携带路径坐标和一个“animationStage”计数器。该计数器将基本上确定路径在“动画”的那个阶段的透明度。 (后期阶段将意味着更加透明。)

然后我将在每个动画帧调用一个函数,该函数将遍历数组中的所有对象并根据它们的坐标和 animationStage 计数器绘制线条,将计数器增加 1,如果 animationStage 计数器将删除数组对象达到结束数字(可能是 50 或其他)。

这一切都可以完成,但听起来并不像所有这些,只需引入一个 setInterval 函数,每次鼠标移动时都会以设定的间隔调用该函数,这样会容易得多。

那么长途跋涉值得吗?不一起使用 setInterval 和 rAF 会更快还是更好的 JS 实践?

在写下所有这些之后,我实际上写了我上面谈到的仅 rAF 代码。粘贴在这里太长了,但规则需要它。在 jsfiddle 上:http://jsfiddle.net/06f7zefn/2/

(我知道有很多效率低下的地方,而且可能是糟糕的编码实践,但请耐心等待,我已经 5 天了!我可以制作一个 isDrawing? bool 值,而不是在每一帧都调用 animate() ,我可以只执行一次 ctx.moveTo(),其余的是 LineTo(),而不必每次迭代都执行 moveTo(),因为一个点起源于另一个点停止的地方)

如果我能理解我正在谈论的主要想法,那就是我征求您的意见的地方。与其让与计时相关的一切都源自 rAF 调用,不如在此处使用 setInterval 或 setTimeout 会更好吗?

var canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);

var ctx = canvas.getContext('2d');

var currentPosX, currentPosY, prevPosX, prevPosY;
var mousePathArray = [];

canvas.addEventListener ('mousemove', mouseOp);


function mouseOp (mouseEvent) {
    prevPosX = currentPosX;
    prevPosY = currentPosY;
    currentPosX = mouseEvent.clientX;
    currentPosY = mouseEvent.clientY;
    mousePathArray.push( {
        x1: currentPosX,
        x2: prevPosX,
        y1: currentPosY,
        y2: prevPosY,
        animStage: 0
    });
}

function animate () {
    var anims = mousePathArray.length;
    if (anims!=0) {
        for (i=0; i<anims; i++) {
            if (mousePathArray[i].animStage == 20) {
                mousePathArray.splice(i, 1);
                i--;
                anims--;
                continue;
            }

            drawLine(mousePathArray[i].x1, mousePathArray[i].x2, mousePathArray[i].y1, mousePathArray[i].y2, 1 - (mousePathArray[i].animStage * 0.05));
            mousePathArray[i].animStage ++;
        }
    }
}

function drawLine (x1, x2, y1, y2, alpha) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.strokeStyle = "rgba(150, 20, 150," + alpha +")";
    ctx.stroke();
}

animloop();

function animloop(){
  window.requestAnimationFrame(animloop);
  gameLoop();
}

function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    animate();
}

最佳答案

我不认为使用 setIntervalsetTimeout 是不好的做法。如果您想在将来做某事,但又不确定何时能够做到,那么使用 setTimeout 是一种不好的做法。例如,这是不好的做法:

makeHeavyDomMovements();
setTimeout(function () {
  //with 3000 timeout I'm sure any device has made my changes
  makeNextMove();
}, 3000);

正确的方法是:

makeHeavyDomMovements().
then(function () {
   makeNextMove();
});

如果你想在未来做一些事情,比如在 100 毫秒后响应用户操作,最好使用 setTimeout 或者如果你想把一些东西放在浏览器队列中,你应该使用 setTimeout(或在需要时使用 worker)。

它与 setInterval 相同,如果您正在使用它来做一些应该每 x 毫秒完成的事情,那么您就正确地使用了它并且这不是坏习惯,这里是 设置间隔:

var dbInterval = setInterval(function () {
  if (dbIsReady()) {
    clearInterval(dbInterval);
    fireReadyEvent();
  }
}, 300);

下面是 setInterval 的常规用法:

setInterval(function () {
  runSync();
}, 600000);

不好的做法和好的做法是由您使用环境工具的方式来定义的,而不是工具本身。

关于javascript - 如果可能的话,我真的不应该使用 setInterval 和 setTimeout 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30722677/

相关文章:

javascript 自动超时按钮操作

javascript - 区分 mouseup mousedown 和 click

javascript - 倒数计时器,setInterval 内的 setInterval?

javascript setInterval() slider

javascript - console.log 在 javascript 中间隔

javascript - 使用位置 : 'Absolute' and display: 'None' in React Native still renders the component

javascript - 使用 jQuery addClass 更改主体 CSS

javascript - db.collection findOne by id 运行但不返回

javascript - 当我的宽度为 : auto and specific left and right, 时,为什么将最小宽度设置为计算宽度的值会将元素扩展 2px?

javascript - JQuery setTimeout - 还有更有效的方法吗?