Sincrónico y asincrónico
introducción
A medida que las aplicaciones web continúan desarrollándose, JavaScript, como lenguaje de programación ampliamente utilizado, también se desarrolla y evoluciona constantemente. En el desarrollo front-end web, JavaScript se utiliza principalmente para el procesamiento de la interfaz de usuario del navegador. El desarrollo de la interfaz de usuario es un modelo típico impulsado por eventos de un solo subproceso, por lo que JavaScript también ha formado un paradigma de programación con procesamiento asincrónico como paradigma de programación principal. Sin embargo, en aplicaciones complejas y a gran escala, los problemas y la complejidad causados por la programación asincrónica son cada vez más obvios.
La aparición de Node.js trae un nuevo paradigma de programación asincrónica a JavaScript: bucles de eventos y funciones de devolución de llamada. Este paradigma de programación es eficiente y conciso, y es adecuado para escenarios de alta concurrencia y de E/S intensivas. Sin embargo, este paradigma de programación también trae sus propios problemas y complejidades. Especialmente en aplicaciones complejas y a gran escala, los programadores deben lidiar con el problema de anidar muchas funciones de devolución de llamada y lidiar con el problema del orden de llamadas asincrónicas, lo que aumenta la complejidad. y dificultad del programa.
Para resolver estos problemas y dificultades, surgieron fibjs. fibjs es un marco de desarrollo de servidor de aplicaciones diseñado principalmente para el desarrollo web back-end, se basa en el motor JavaScript de Google v8 y elige una solución de concurrencia diferente a la devolución de llamada tradicional. fibjs utiliza fibra para aislar la complejidad empresarial causada por llamadas asincrónicas en la capa de marco, lo que reduce en gran medida la dificultad de desarrollo y los problemas de rendimiento causados por el procesamiento asincrónico frecuente en el espacio del usuario. Al mismo tiempo, en comparación con el paradigma de programación asincrónica tradicional, su paradigma de programación sincrónica tiene las ventajas de mayor legibilidad, lógica simple y fácil mantenimiento.
En el siguiente contenido, presentaremos las ventajas y características de fibjs y explicaremos cómo utilizar sus soluciones de programación sincrónica y asincrónica a través de ejemplos.
introducción de fibra
fibjs es un marco de servidor JavaScript de alto rendimiento basado en el motor v8, principalmente para desarrollo web back-end. Iniciado en 2009, ya tiene alta estabilidad y productividad, y tiene una amplia gama de casos de aplicación en el país y en el extranjero.
En fibjs, la fibra se utiliza para resolver el problema entre la lógica empresarial y el procesamiento de E/S. La fibra se diferencia de conceptos tradicionales como subprocesos, corrutinas y procesos: es un subproceso liviano a nivel de usuario que puede considerarse como un mecanismo cooperativo multitarea. La fibra puede realizar lógica empresarial y operaciones de E/S en diferentes contextos y gestionar recursos internamente mediante preasignación y reciclaje. En comparación con los subprocesos y procesos tradicionales, es más ligera, más flexible y más eficiente.
En comparación con otras bibliotecas de subprocesos (como pthread, WinThread, Boost.Thread, etc.), la fibra tiene las siguientes ventajas:
Programación colaborativa : Fiber es una programación colaborativa que no requiere programación preventiva por parte del kernel o del sistema operativo, reduce el cambio de contexto frecuente, acelera la velocidad de ejecución del programa y evita condiciones de competencia y problemas de punto muerto entre subprocesos.
Ligero : cada fibra solo consume un pequeño espacio de pila y se puede crear una gran cantidad de fibras en aplicaciones multiconcurrentes sin causar el problema de ocupar demasiada memoria.
Eficiencia : la fibra se implementa en función de las características del propio lenguaje JavaScript y aprovecha al máximo el rendimiento superior del motor v8, que es más rápido que las bibliotecas de subprocesos tradicionales.
Al utilizar fibra, fibjs puede separar la lógica empresarial y el procesamiento de E/S, encapsulando así llamadas asincrónicas en llamadas sincrónicas, haciendo que escribir y mantener código sea más simple y fácil de leer, y al mismo tiempo aprovechar al máximo las ventajas de Lenguaje JavaScript.
Programación síncrona en fibjs.
En la programación asincrónica, el anidamiento de funciones de devolución de llamada puede provocar una mala legibilidad del código, causar fácilmente el problema del infierno de devolución de llamada y aumentar la dificultad del código y el costo de depuración. El paradigma de programación sincrónica está más en línea con los patrones de pensamiento humano, lo que hace que la estructura del código sea más clara, más fácil de leer y de mantener, lo que puede mejorar en gran medida la eficiencia del desarrollo y la calidad del código.
En fibjs, la programación síncrona es un paradigma de programación muy popular y de uso común, lo que hace que la estructura y la lógica del código sean más intuitivas, fáciles de entender y mantener. Algunas funciones y módulos de programación síncrona son altamente compatibles con fibjs, como util.sync, fs.readSync, etc.
En fibjs, puede llamar directamente a funciones asincrónicas de objetos integrados de forma sincrónica:
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
También puede envolver la función asincrónica a través de util.sync y try...catch, para que la fibra pueda obtener el valor de retorno de la llamada asincrónica, logrando así el efecto de sincronización, por ejemplo:
1
2
3
4
5
6
7
8
9
10
11
12
13// load module
const coroutine = require("coroutine");
const util = require("util");
const fs = require("fs");
// use util.sync to wrap fs.readFile
function readFile(path) {
return util.sync(fs.readFile)(path);
}
// call the sync function
const data = readFile("myfile.txt");
console.log(data);
En el ejemplo anterior, definimos una función llamada readFile y usamos util.sync para encapsular la función asincrónica fs.readFile en una función sincrónica, que puede devolver datos directamente a través de llamadas sincrónicas. Este método de llamada sincrónica es similar al paradigma de programación JavaScript tradicional, la diferencia es que en fibjs el hilo no se bloquea, pero el efecto asincrónico se logra a través de fibra.
Cómo funciona util.sync
util.sync es una función contenedora eficiente del kernel. El siguiente código JavaScript puede lograr funciones similares:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const coroutine = require("coroutine");
function sync(func) {
return function _warp() {
var ev = new coroutine.Event();
var e, r;
func.apply(this, [
...arguments,
function (err, result) {
e = err;
r = result;
ev.set();
}
]);
ev.wait();
if (e)
throw e;
return r;
}
}
Este código define una función de herramienta de sincronización para convertir una función de devolución de llamada asíncrona en una función de llamada síncrona. Recibe una función func y devuelve una nueva función _wrap. Esta nueva función implementa la función de convertir la función original en una llamada sincrónica. En la función _wrap, primero se crea un nuevo objeto de evento ev para la programación de subprocesos y la espera de resultados de devolución de llamada asincrónica. Luego use el método de aplicación para llamar a la función original func con los parámetros especificados y una nueva función de devolución de llamada como parámetros. Durante el proceso de llamada, se produce una devolución de llamada asincrónica y la nueva función de devolución de llamada almacena los resultados devueltos en las variables e y r y activa el objeto Evento. Finalmente, se decide según la variable e si se lanza una excepción o se devuelve la variable r. Esta función implementa una solución para convertir funciones de devolución de llamada asincrónicas en llamadas sincrónicas, lo que puede mejorar la legibilidad y el mantenimiento de la función.
Programación asincrónica en fibjs
En fibjs, la mayoría de los métodos asincrónicos (incluidos los métodos de solicitud de red y de E/S, etc.) pueden admitir llamadas tanto sincrónicas como asincrónicas, lo que permite a los desarrolladores elegir qué método utilizar de acuerdo con sus necesidades de programación en cualquier momento.
Tomando fs.readFile() como ejemplo, podemos usar este método de dos maneras:
Método asincrónico: procese el resultado de leer el archivo pasando una función de devolución de llamada, por ejemplo:
1
2
3
4
5
6const fs = require("fs");
fs.readFile("/path/to/file", (err, data) => {
if (err) throw err;
console.log(data);
});
Este método es adecuado para situaciones en las que necesita realizar algunas operaciones después de leer el archivo.
Método síncrono: obtenga el contenido del archivo sin pasar una función de devolución de llamada, por ejemplo:
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
En este ejemplo, obtenemos el contenido del archivo leyendo los datos del valor de retorno del archivo. No es necesario esperar a que la función de devolución de llamada complete la lectura del archivo antes de continuar con la operación. Este método es adecuado para situaciones en las que necesita realizar algunas operaciones antes de que se complete la lectura del archivo.
Se puede ver que esta característica de admitir llamadas sincrónicas y asincrónicas permite a los desarrolladores elegir utilizar diferentes métodos según sus propias necesidades y escenarios de desarrollo. En algunos casos, el código sincrónico es más legible y más fácil de mantener y depurar; mientras que, en algunos casos, el código asincrónico puede mejorar mejor la velocidad de respuesta y el rendimiento del código.
Sin embargo, debe tener cuidado al utilizar el método de sincronización. En algunos escenarios, este método puede bloquear la fibra actual. Por lo tanto, debemos elegir el método de programación adecuado según las necesidades reales.
en conclusión
En este artículo, presentamos el estilo de programación síncrona y las soluciones de programación asincrónica de fibjs, así como sus ventajas y escenarios de aplicación. Mencionamos que fibjs puede reducir la complejidad operativa y mejorar la eficiencia del desarrollo de código mediante el uso de fibra para aislar la lógica empresarial y los problemas de rendimiento causados por el procesamiento asincrónico. Al mismo tiempo, también enfatizamos las ventajas de fibjs en el procesamiento de E/S y la gestión de memoria, lo que aporta una gran comodidad al desarrollo, las pruebas y el mantenimiento.
Finalmente, animamos a los lectores a explorar fibjs en profundidad y participar en las contribuciones y actividades comunitarias de fibjs. Creemos que fibjs seguirá atrayendo la atención y el apoyo de la comunidad de código abierto con su potente rendimiento y facilidad de uso.