javascript 调用一次然后根据布尔状态重置的函数

javascript function that is called once and then reset according to a boolean state

我正在寻找一个调用一次然后根据布尔状态重新准备的函数。

经过一番研究后,我发现保罗在下面的回答是在绘图循环内执行/重新准备函数的有效方法。

但是我发现,在将此代码与 class 合并时,for 循环中有多个实例,每个实例都会触发和重置该函数多次。根据我下面的示例代码。

let instances = [];

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < 4; i++) {
    instances.push(new Ball(50, random(30,370)));
  }
}

const [happenOnce, reset] = makeRunOnce(() => {
  console.log("ball has crossed the line!");
});

function makeRunOnce(fn) {
  let hasRun = false;
  return [
    // run
    () => {
      if (!hasRun) {
        fn();
        hasRun = true;
      }
    },
    // reset
    () => {
      hasRun = false;
    }
  ]
}

function draw() {
  background(220);
  line(200, 0, 200, height);
  
  for (let i = 0; i < instances.length; i++) {
    instances[i].showBall();
    instances[i].moveBall();
    
    if(instances[i].returnTrue()) {
      happenOnce();
    } else {
      reset();
    }
  }
}

class Ball{
  constructor(x, y) {
    this.x = x;
    this.y = y
    this.r = 10;
    this.t = random();
  }
  
  showBall() {
    ellipse(this.x, this.y, this.r * 2);
  }
  
  moveBall() {
    this.x += this.t;
  }
  
  returnTrue() {
    return this.x + this.r > 200;
  }
}

有人对我如何让函数在 class 方法 returns true 时执行一次并在每个实例为 false 时重置有任何建议吗?

看起来你可能把事情复杂化了一点,但你在这里所需要的只是能够将 executed 标志重置回 false。这是一个带有辅助函数 makeRunOnce 的示例,它在数组中接受一个函数和 returns 两个函数。第一个函数仅在第一次调用时运行原始函数(最初或重置后),第二个函数将状态重置为未调用。为了测试这个例子,第一次点击绘制一个圆圈,额外的点击将被忽略,直到你双击重置状态,以便下一次点击将绘制另一个圆圈。

function setup() {
  createCanvas(windowWidth, windowHeight);
}

const [drawCircleOnce, resetDrawCircle] = makeRunOnce(() => {
  ellipse(mouseX, mouseY, 20, 20);
});

let mouseHasBeenClicked = false;

function draw() {
  if (mouseHasBeenClicked) {
    drawCircleOnce();
  } else {
    resetDrawCircle();
  }
}

// Note: instead of setting the mouseHasBeenClicked flag here
// we could just call drawCircleOnce() directly, and then
// resetDrawCircle() in doubleClicked. The draw() function would
// then be a no-op. I've use this flag to more closely 
// approximate the apparent structure of your code.
function mouseClicked() {
  mouseHasBeenClicked = true;
}

function doubleClicked() {
  // reset
  mouseHasBeenClicked = false;
}

function makeRunOnce(fn) {
  let hasRun = false;
  return [
    // run
    () => {
      if (!hasRun) {
        fn();
        hasRun = true;
      }
    },
    // reset
    () => {
      hasRun = false;
    }
  ]
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>