在HTML画布上依次绘制连续的线条

Ram*_*ata 8 javascript canvas promise

我正在尝试为上述问题编写代码.我试着寻找解决方案.这就是我现在拥有的.

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

var drawColorLine = function(start, end, color) {
  var deltaX, deltaY, i = 0,
    currLength = 0,
    isHor, isVert;

  deltaX = end[0] - start[0];
  deltaY = end[1] - start[1];
  context.strokeStyle = color;

  isHor = deltaX === 0 ? 0 : 1;
  isVert = deltaY === 0 ? 0 : 1;

  function draw() {
    context.beginPath();
    context.moveTo(start[0] + currLength * isHor, start[1] + currLength * isVert);

    currLength = currLength + 0.5 * i;
    context.lineTo(start[0] + currLength * isHor, start[1] + currLength * isVert);
    context.stroke();

    if (currLength <= Math.max(deltaX, deltaY)) {
      i = i + 1;
      requestAnimationFrame(draw);
    }
  }
  draw();
};

drawColorLine([40, 40], [100, 40], '#116699');
drawColorLine([40, 40], [40, 100], '#bb11dd');
Run Code Online (Sandbox Code Playgroud)
<canvas id='canvas' width='400' height='400'></canvas>
Run Code Online (Sandbox Code Playgroud)

问题是两者同时被绘制出来.一个人应该追随另一个人.使用promsises是否可以在第一个函数执行时延迟第二个函数,然后执行第二个函数?我尝试了一下Promises,但我无法将我理解的内容翻译成代码.

提前致谢.

Ber*_*rgi 5

是的,您可以使用promises,尽管出于学习目的,您可能希望首先编写纯回调解决方案.

您需要查看我承诺开发的经验法则.我们在这里应用它们:

  1. 每个异步函数都必须返回一个promise.

    在你的情况下,这些将是drawColorLine,.drawrequestAnimationFrame

  2. 由于requestAnimationFrame原生的,原始的异步函数不幸仍然需要回调,我们必须实现它:

    function getAnimationFrame() {
        return new Promise(function(resolve) {
            requestAnimationFrame(resolve); // this promise never gets rejected
            // TODO: cancellation support :-)
        });
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 异步操作之后的所有内容都会进入.then()回调:

    function drawColorLine(start, end, color) {
        … // initialisation
    
        function draw() {
            … // do work
            // always return a promise:
            if (/* furter work */) {
                i++;
                return getAnimationFrame().then(draw); // magic happens here :-)
            } else {
                return Promise.resolve(…); // maybe have a path object as eventual result?
                                           // or anything else, including nothing (no arg)
            }
        }
        return draw(); // returns a promise - but don't forget the `return`
    }
    
    Run Code Online (Sandbox Code Playgroud)

瞧!

drawColorLine([40, 40], [100, 40], '#116699').then(function() {
    return drawColorLine([40, 40], [40, 100], '#bb11dd');
}).then(console.log.bind(console, "both lines drawn"));
Run Code Online (Sandbox Code Playgroud)