Como sabrán, el entorno de ejecución del idioma JavaScript es "un solo hilo".
El llamado "hilo único" significa que una tarea solo se puede completar a la vez. Si hay múltiples tareas, debe hacer cola, completar la tarea anterior, ejecutar la siguiente tarea, y así sucesivamente.
La ventaja de este modelo es que es relativamente simple de implementar y el entorno de ejecución es relativamente simple; ejecución de todo el programa. Los navegadores comunes no responden (muerte falsa) a menudo porque un cierto código de JavaScript se ejecuta durante mucho tiempo (como un bucle muerto), lo que hace que toda la página esté atrapada en este lugar y no se puede ejecutar otras tareas.
Para resolver este problema, el lenguaje JavaScript divide el modo de ejecución de las tareas en dos tipos: sincrónico (sincrónico) y asíncrono (asíncrono).
"Modo sincrónico" es el modo de la sección anterior, y la última tarea espera que la tarea anterior finalice, y luego la ejecuta. Completamente diferente, y cada tarea es una o más funciones de devolución de llamada (devoluciones de llamada). Para terminar, la orden de ejecución del programa es y la tarea.
El "modo async" es muy importante. En el lado del navegador, las operaciones a largo plazo deben ejecutarse asincrónicamente para evitar que el navegador pierda respuesta. En el lado del servidor, el "modo asíncrono" es incluso el único modo, porque el entorno de ejecución es de un solo hilo, si todas las solicitudes HTTP pueden ejecutarse sincrónicamente, el rendimiento del servidor disminuirá bruscamente y pronto perderá su respuesta.
1. Función de devolución de llamada
Este es el método más básico de programación asincrónica.
Supongamos que hay dos funciones F1 y F2, esta última esperando el resultado de la ejecución del primero.
La copia del código es la siguiente:
f1 ();
f2 ();
Si F1 es una tarea que requiere mucho tiempo, puede considerar reescribir F1 y escribir F2 como la función de devolución de llamada de F1.
La copia del código es la siguiente:
función f1 (devolución de llamada) {
setTimeOut (function () {
// Código de tarea de F1
llamar de vuelta();
}, 1000);
}
El código de ejecución se vuelve así:
F1 (F2);
La ventaja de las funciones de devolución de llamada es que son simples, fáciles de entender e implementar, y la desventaja es que no son propicias para la lectura y el mantenimiento del código. Sea muy caótico, y cada tarea solo puede especificar una función de devolución de llamada.
2. Monitoreo de eventos
Otra idea es adoptar un modelo basado en eventos. La ejecución de una tarea no depende del orden del código, sino de si ocurre un evento.
Tomemos F1 y F2 como ejemplos. Primero, vincule un evento para F1 (el método de escritura jQuery utilizado aquí).
La copia del código es la siguiente:
f1.on ('hecho', f2);
La línea de código anterior significa que cuando el evento hecho ocurre en F1, F2 se ejecuta. Entonces, reescribe F1:
La copia del código es la siguiente:
función f1 () {
setTimeOut (function () {
// Código de tarea de F1
f1.rigger ('Done');
}, 1000);
}
F1.trigger ('hecho') significa que después de completar la ejecución, el evento hecho se activa de inmediato, comenzando a ejecutar F2.
La ventaja de este método es que es relativamente fácil de entender. La desventaja es que todo el programa se basará en eventos, y el proceso de operación quedará muy poco claro.
3. Publicar/suscribirse
El "evento" en la sección anterior puede entenderse completamente como una "señal".
Suponemos que hay un "centro de señal". Esto se llama "Publicado Patrón de suscripción", también conocido como "Patrón de Observador".
Hay muchas implementaciones de este modelo.
Primero, F2 se suscribe a la señal "Hecha" a la jQuery "Centro de señal".
La copia del código es la siguiente:
jQuery.subscribe ("Hecho", F2);
Entonces, F1 se reescribe de la siguiente manera:
La copia del código es la siguiente:
función f1 () {
setTimeOut (function () {
// Código de tarea de F1
jQuery.publish ("hecho");
}, 1000);
}
jQuery.publish ("hecho") significa que después de que se completa la ejecución de F1, se emite una señal "realizada" a la jQuery "Centro de señal", lo que desencadena la ejecución de F2.
Además, después de que se ejecuta F2, la cancelación de suscripción también se puede dejar de suscripción.
La copia del código es la siguiente:
jQuery.UnsubScribe ("hecho", f2);
La naturaleza de este enfoque es similar a la "escucha de eventos", pero es significativamente mejor que el último. Debido a que podemos monitorear el funcionamiento del programa observando el "centro de mensajes" para comprender cuántas señales existen y cuántos suscriptores son para cada señal.
4. Promesas objeto
El objeto Promeses es una especificación propuesta por el grupo de trabajo CommonJS, con el propósito de proporcionar una interfaz unificada para la programación asincrónica.
En pocas palabras, su idea es que cada tarea asincrónica devuelve un objeto prometedor, que tiene un método entonces que permite especificar la función de devolución de llamada. Por ejemplo, la función de devolución de llamada F2 de F1 se puede escribir como:
La copia del código es la siguiente:
F1 (). Entonces (F2);
F1 debe reescribirse de la siguiente manera (la implementación de jQuery se usa aquí):
La copia del código es la siguiente:
función f1 () {
var dfd = $ .deferred ();
setTimeOut (function () {
// Código de tarea de F1
dfd.resolve ();
}, 500);
return dfd.promise;
}
La ventaja de escribir de esta manera es que la función de devolución de llamada se ha convertido en un método de escritura en cadena, y el flujo del programa se puede ver muy claramente, y hay un conjunto completo de métodos de apoyo que puede realizar muchas funciones poderosas.
Por ejemplo, especifique múltiples funciones de devolución de llamada:
F1 (). Entonces (F2) .Then (F3);
Por ejemplo, especifique la función de devolución de llamada cuando ocurre un error:
f1 (). Entonces (F2) .fail (F3);
Además, tiene una ventaja que ninguno de los tres métodos anteriores tiene: si se ha completado una tarea, agregue una función de devolución de llamada y la función de devolución de llamada se ejecutará de inmediato. Por lo tanto, no tiene que preocuparse por perderse un evento o señal. La desventaja de este método es que es relativamente difícil de escribir y comprender.