Acerca de los temporizadores de JavaScript

Los temporizadores de JavaScript son una excelente característica para implementar comportamientos de bucle o incluso desencadenar acciones retrasadas. Los temporizadores pueden proporcionar soporte para cualquier lógica basada en el tiempo que tenga. Hay dos funciones de temporizador en JavaScript: setTimeouty setInterval. Veamos qué son los temporizadores y cómo funcionan.

Puntos clave sobre los temporizadores

Antes de profundizar en los detalles de los temporizadores, hay algunos puntos muy importantes a tener en cuenta.

no del todo exacto

Un temporizador activa una acción después de una cierta cantidad de segundos o repite una acción cada vez que transcurre el tiempo de espera especificado. Sin embargo, si bien la expectativa podría ser que sean precisos al segundo, este no es el caso.

La especificación de estos temporizadores establece que utilizarán un parámetro de tiempo (como un número específico de segundos) como el tiempo de espera mínimo. Pero si hay otras tareas que deben realizarse primero, definitivamente tomarán más tiempo.

Esto solo se convierte en un problema si su lógica se basa en una medición precisa del tiempo, como hacer que un reloj cuente los segundos a través de una setIntervaldevolución .

función asíncrona

Esto significa que no detienen el flujo del programa hasta que terminan. Incluso si se especifica 0como un valor de tiempo de espera, su comportamiento sigue siendo asíncrono.

Esto significa que estas funciones agregarán una referencia a la función que desean activar en el ciclo de eventos, por lo que incluso si se especifica en el valor de tiempo de espera 0, la referencia se pondrá en cola después de todo lo que suceda a continuación.

establecer tiempo de espera

setTimeoutLas funciones son probablemente las más fáciles de entender porque el objetivo principal es activar una función después de unos segundos, que solo se ejecutará una vez.

Los parámetros de esta función son los siguientes:

  • Referencia de función para ejecutar: Esta es la lógica del código que se activará cuando llegue el momento.
  • Número de segundos a esperar antes de la ejecución de la función
  • Todos los demás argumentos se pasan a la función ejecutada en el mismo orden.

El siguiente código se imprimirá después de 3unos segundos Hello World:

setTimeout(console.log, 3000, "Hello", "World");
复制代码

es equivalente al siguiente código:

setTimeout(
    (strHello, strWorld) => {
        console.log(strHello, strWorld);
    },
    3000,
    "Hello",
    "World"
);
复制代码

setTimeoutes un tipo especial de función asíncrona, por lo que cualquier código que se escriba después se ejecutará antes de que se active la función, de la siguiente manera:

console.log("执行了第 1 行代码");
setTimeout(() => {
    console.log("执行了第 3 行代码");
}, 1000);
console.log("执行了第 5 行代码");
console.log("执行了第 6 行代码");
setTimeout(function () {
    console.log("执行了第 8 行代码");
}, 0);
console.log("执行了第 10 行代码");
复制代码

Los resultados de salida son los siguientes:

执行了第 1 行代码
执行了第 5 行代码
执行了第 6 行代码
执行了第 10 行代码
执行了第 8 行代码
执行了第 3 行代码
复制代码

Observe cómo las líneas 3 y 8 se ejecutan al final, aunque el tiempo de espera para la línea 8 es 0.

在讨论 setTimeout 之前,如果设置超时值然后意识到必须停止它会发生什么?可以定义一个变量保存 setTimeout 的返回值(计时器 ID),则可以使用 clearTimeout 函数在超时之前停止计时器。

console.log("执行了第 1 行代码");
const timerId = setTimeout(() => {
    console.log("执行了第 3 行代码");
}, 1000);
console.log("执行了第 5 行代码");
clearTimeout(timerId);
console.log("执行了第 6 行代码");
setTimeout(function () {
    console.log("执行了第 8 行代码");
}, 0);
console.log("执行了第 10 行代码");
复制代码

执行结果如下,少了一个定时器的输出:

执行了第 1 行代码
执行了第 5 行代码
执行了第 6 行代码
执行了第 10 行代码
执行了第 8 行代码
复制代码

setInterval

setInterval 函数与 setTimeout 非常相似,但它不是只触发一次函数,而是一直触发函数直到停止。

此函数的签名与 setInterval 函数的签名完全相同,所有参数的也相同。

const names = ["刘备", "关羽", "张飞", "赵云", "黄忠"];

function sayHi(list) {
    let name = list[Math.round(Math.random() * 10) % 4];
    console.log("你好!", name);
}
console.log("蜀汉五虎将");
const intervalID = setInterval(sayHi, 1000, names);

setTimeout(() => {
    clearTimeout(intervalID);
}, 4000);
复制代码

上面的代码将启动一个每 1 秒触发一次的循环,当它触发时,将选择一个随机名称并打印字符串 你好! <name>。设置了 4 秒的超时时间,通过调用 clearTimeout 函数来结束无限循环。当然,也可以使用 clearInterval 函数,但由于它们使用相同的计时器池,可以互换使用它们。

区别

setTimeout 仅触发一次表达式,而 setInterval 在给定的时间间隔后保持定期触发表达式(除非手动终止)。

使用场合

除了执行定时操作,结合 Promise 方法,结合 setTimeout 可以实现休眠功能。

const sleep = (ms) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
};
const asyncFoo = async () => {
    await sleep(2000);
    console.log("  等待2秒输出");
    await sleep(1000);
    console.log("    等待1秒输出");
};
console.log("开始执行");
asyncFoo();
复制代码

Promise 结合 setInterval 可以实现一些数据的最大检测次数,如某个数据通过API验证,验证结果无法给出正常结果,超过一定次数提示错误。

const fakeApiCheck = async () => {
    console.log("检查中...");
    return Math.random() > 0.8;
};
const asyncInterval = async (callback, ms, triesLeft = 5) => {
    return new Promise((resolve, reject) => {
        const interval = setInterval(async () => {
            if (await callback()) {
                resolve();
                clearInterval(interval);
            } else if (triesLeft <= 1) {
                reject();
                clearInterval(interval);
            }
            triesLeft--;
        }, ms);
    });
};
const dataCheck = async () => {
    try {
        await asyncInterval(fakeApiCheck, 500);
    } catch (e) {
        console.log("验证错误");
    }
    console.log("验证完成!");
};
dataCheck();
复制代码

总结

计时器是生成重复或延迟行为的绝佳函数,它们非常有用,尤其是当必须在某些基于时间的条件下与其他服务进行交互时。超时和间隔都可以在使用 clearInterval 或者 clearTimeout 函数触发之前强制停止。

Supongo que te gusta

Origin juejin.im/post/7194022475880431676
Recomendado
Clasificación