Lea el siguiente código y adivine el resultado de la ejecución:
var inicio = nueva fecha; setTimeOut (function () {console.log ('Time pasa:'+(nueva fecha - inicio)+'msec');}, 200); while (nueva fecha - start <1000) {} console.log (1); function dosoming () {setTimeout (function () {console.log ('El tiempo pasa nuevamente:'+(nueva fecha - inicio)+'msec');}, 10);} dosoMing (); while (nueva fecha - inicio <2000) {} console.log (2);apagar:
Salida después de aproximadamente 1 segundo: 1,
Después de aproximadamente 1 segundo, la salida es: 2.
Luego, salida inmediatamente: Tiempo pasado: 2002 milisegundos
Último resultado: tiempo pasó nuevamente: 2003 milisegundos
¿Lo has adivinado bien?
Aquí, todas las funciones que retrasan la ejecución por SetTimeout se introducen hasta el final antes de la ejecución;
El principio es el siguiente:
En el entorno del navegador existente, el motor de ejecución de JavaScript es de un solo hilo. Las declaraciones y métodos del hilo principal bloquearán la ejecución de las tareas de tiempo. Fuera del motor de ejecución de JavaScript, hay una cola de tareas. Cuando se llama al método setTimeOut () en el código, el método de retraso registrado se colgará a otros módulos en el núcleo del navegador para su procesamiento. Cuando el método de retraso alcanza la condición de activación, es decir, el tiempo de retraso del conjunto alcanza el conjunto, el módulo agregará el método que se ejecutará a la cola de tareas del módulo. Este proceso es independiente del hilo principal del motor de ejecución. El motor de ejecución extraerá tareas de la cola de tareas del módulo en secuencia para ejecutar cuando se ejecuta el método de subproceso principal y alcanza el estado inactivo. El tiempo durante este período puede ser mayor que el tiempo de retraso establecido al registrar la tarea;
Cuando el navegador está inactivo, intentará extraer constantemente tareas de la cola de tareas del módulo, que se llama modelo de bucle de eventos;
Veamos hacia atrás al código anterior. ¡El tiempo de retraso del segundo método de retraso setTimeOut () es de 10 milisegundos, que se activa antes del primero! ¿Por qué está detrás del resultado de la ejecución? Debido a que fue bloqueado por el código anterior para aproximadamente 1000.5 ~ 1001 milisegundos (dependiendo de la velocidad de procesamiento del navegador), cuando cuelga al módulo de procesamiento y cuando el tiempo de activación se agrega a la cola de tareas, el primer método de retraso setTimeOut () se ha agregado durante mucho tiempo al equipo de tareas del módulo, y el hilo principal del motor se obtiene en orden, por lo tanto, debería entender, ¿verdad?
Ahora, si cambia la anterior while (nueva fecha - inicio <1000) {} a while (nueva fecha - inicio <189) {} o while (nueva fecha - inicio <190) {}, ¿cuál es el resultado? ¡No diré mucho! ¡Actualice el navegador 20 veces cada uno y vea los resultados usted mismo!
El método SetInterval () y SetTimeOut () tienen el mismo estado. Cuando se llama al método SetInterval (), el método de retraso registrado se colgó al módulo para su procesamiento. Cada vez que llega el tiempo de activación, el método a ejecutar se agrega a la cola de tareas una vez;
Echemos un vistazo a la sintaxis de SetTimeOut:
var timeId = window.setTimeout (func, demora, [param1, param2, ...]);
var timeId = window.setTimeout (código, retraso);
SetTimeOut y SetInterval son métodos de objetos de ventana (se puede omitir la ventana). Los segundos parámetros opcionales (no compatibles con IE9 y versiones antiguas) son los parámetros pasados a FUNC. Cada vez que se les llama, se devolverá una ID numérica (es solo un número impreso en el navegador, pero la imprimí en Webstorm y descubrí que en realidad es un objeto con muchos atributos). Esta ID mantiene la información relevante de su SetTimeOut correspondiente o SetInterval, y se usa principalmente para borrarla (o cerrar) en el módulo central y la cola de tareas (utilizando los métodos ClearTimeOut (ID) y ClearInterval (ID)).
Si necesita pasar un parámetro a su función de devolución de llamada, el siguiente es el método de escritura compatible con IE
if (document.all &&! window.settimeout.ispolyfill) {var __nativest__ = window.setTimeout; Window.setTimeOut = function (vCallback, ndelay, param1, param2, param3) {var aargs = array.prototype.slice.call (argumentos, 2); return __nativeSt __ (vCallback instanceOf function? function () {vcallback.apply (null, aargs);}: vcallback, ndelay); }; Window.setTimeout.ispolyFill = true;}Se produce un error común cuando se usa cierres en un bucle
for (var i = 0; i <10; i ++) {setTimeOut (function () {console.log (i);}, 1000);}El código anterior generará el número 10 diez veces. ¿Por qué? ¡Cierre!
Cuando se llama a console.log, aunque la función anónima mantiene una referencia a la variable externa I, el bucle for ha terminado en este momento y el valor de I se modifica a 10.
Para obtener el resultado deseado, una copia de la variable que debo crear en cada bucle.
Para obtener el número de bucle correctamente, es mejor usar un envoltorio anónimo (en realidad, lo que generalmente llamamos funciones anónimas de auto-ejecutación).
for (var i = 0; i <10; i ++) {(function (e) {setTimeOut (function () {console.log (e);}, 1000);}) (i);}La función anónima externa se ejecutará inmediatamente y se utilizará como su parámetro. En este momento, la variable E en la función tendrá una copia de I.
Cuando se ejecuta la función anónima pasada a SetTimeOut, tiene una referencia a E, y este valor no cambiará por el bucle.
Hay otra forma de hacer el mismo trabajo; Eso es devolver una función de un envoltorio anónimo. Esto funciona igual que el código anterior.
for (var i = 0; i <10; i ++) {setTimeOut ((function (e) {return function () {console.log (e);}}) (i), 1000)}Otra aplicación importante: Function Throttle and Function DeBounce
Consulte alguna información que recopilé de Internet:
JavaScript - Función de optimización de rendimiento Acelerador y funciones de desbordamiento
Enlace de referencia:
https://developer.mozilla.org/zh-cn/docs/web/api/window/settimeout
http://www.alloyteam.com/2015/10/Turning-to-JavaScript-Series-from-SetTimeout-Said-The-Event-loop-Model/#prettyphoto
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.