如何使用 setInterval 函数在屏幕上出现的每个值之间以 500 毫秒的间隔显示阶乘计算?

How to use the setInterval function to display a factorial calculation with a 500ms interval in between each value appearing on screen?

我需要在我的程序中实现 setInterval 函数,以便在屏幕上出现的每个值之间创建 500 毫秒的间隔。我目前使用的程序代码从用户那里获取输入值并写出,并计算因式分解的答案。

function factorizeFunction(number, numberArray = []) { //this is the function that does the factorization calculations
  if (number == 0 || number == 1) numberArray.push(number);
  else {
    numberArray.push(number);
    factorizeFunction(number - 1, numberArray);
  }
  return numberArray.join(' * ') + ' = ' + numberArray.reduce((a, b) => a * b, 1);
}
document.getElementById("factorialTest").innerHTML = factorizeFunction(number);

我需要知道答案,例如:6 * 5 * 4 * 3 * 2 * 1 = 720 在我的网页上显示,一次每个值,显示之间有 500 毫秒的延迟。所以,6(500 毫秒延迟)*(500 毫秒延迟)5(500 毫秒延迟)...等等。我不确定我会怎么做?

您可以用 setInterval():

封装您的函数
function startInterval(number, numberArray){
   setInterval(() => factorizeFunction(number, numberArray), 500);
}

当您希望网页开始显示数字时,调用 startInterval 而不是 factorizeFuncion

这是一个很好的练习。

const factorizeFunction = async num => {
    if (num < 1) return;
    let resDiv = document.querySelector('#res_div');
    let numArr = [];
    while (num >= 1)
        numArr.push(num--);
    for (let i = 0; i < numArr.length; i++) {
        resDiv.append(numArr[i]);
        await _delay(500);
        if (i < (numArr.length - 1))
            resDiv.append(' * ');
        else if (i == (numArr.length - 1))
            resDiv.append(' = ');
        await _delay(500);
    }
    resDiv.append(numArr.reduce((a, b) => a * b, 1));
};
let _delay = (ms = 200) => new Promise((accept) => setTimeout(accept, ms));
factorizeFunction(6);
<div id="res_div"></div>

三种不同的方法。

inSequence构造一个promise链:

const factorizeFunction = () => '6 * 5 * 4 * 3 * 2 * 1 = 720' // your existing function
const inSequence = async (arr) => arr.reduce((acc, f) => acc.then(f), Promise.resolve())
const delayed = (fn, ms = 500) => (...args) => () => new Promise((res) => setTimeout(() => { res(fn(...args)) }, ms))
const tokenize = (str) => str.match(/[\S]+[\s]?/g)
const print = (str) => document.getElementById("output").innerHTML += str

const printFactorialString = (str) => inSequence(tokenize(str).map((t) => delayed(print)(t)))

printFactorialString(factorizeFunction())
<div id="output"><div>

以下方法使用间接递归:

const factorizeFunction = () => '6 * 5 * 4 * 3 * 2 * 1 = 720' // your existing function
const delay = (ms = 500) => new Promise((resolve) => setTimeout(resolve, ms))
const slowly = (action) => {
    return async function go ([i, ...remaining]) {    
        if(!i) return
        action(i)
        await delay()
        go(remaining)
    }
}
const tokenize = (str) => str.match(/[\S]+[\s]?/g)
const print = (str) => document.getElementById("output").innerHTML += str

const printFactorialString = (str) => slowly(print)(tokenize(str))

printFactorialString(factorizeFunction())
<div id="output"></div>

此解决方案使用异步生成器和 async...await:

const factorizeFunction = () => '6 * 5 * 4 * 3 * 2 * 1 = 720' // your existing function
const identity = (x) => x
const delayed = (fn, ms = 500) => (...args) => () => new Promise((res) => setTimeout(() => { res(fn(...args)) }, ms))
const asyncIterable  = (arr) => async function* () { for(let i of arr) yield i() }
const tokenize = (str) => str.match(/[\S]+[\s]?/g)
const print = (str) => document.getElementById("output").innerHTML += str

const printFactorialString = async (str) => {
    const generator = asyncIterable(tokenize(str).map((t) => delayed(identity)(t)))()
    for await (let x of generator) { print(x) }
}

printFactorialString(factorizeFunction())
<div id="output"></div>

基本上,您想要在屏幕上打印的所有内容、运算符和数字都需要以 500 毫秒的延迟出现。这意味着最好先获取这些元素的数组:

function getFactorElements(factor) {
  // get array like [1, 2, 3, 4]
  const factorArray = Array.from({ length: factor }, (_, i) => i + 1);

  // calculate result
  const result = factorArray.reduce((a, b) => a * b, 1);

  // insert math operators
  const parts = factorArray
    .reverse()
    .map((part) => [ part, part > 1 ? '*' : '=' ])
    .reduce((a, b) => a.concat(b));

  parts.push(result);

  return parts;
}

这是你的HTML

<div id="factorialTest"></div>

您可以创建另一个接受元素和因子的函数:

async function showFactorCalculation(element, factor) {
  element.innerHTML = '';

  for (const part of getFactorElements(factor)) {
    element.innerHTML += ' ' + part;
    await new Promise((resolve) => setTimeout(resolve, 500));
  }
}

你应该这样称呼:

showFactorCalculation(document.getElementById('factorialTest'), 9);

我在这里为您准备了工作堆栈 ;):

stack

我正在使用 setTimeout 因为主要不鼓励使用 setInterval