síncrono y asíncrono
introducción
A medida que las aplicaciones web continúan creciendo, JavaScript, un lenguaje de programación ampliamente utilizado, continúa creciendo y evolucionando. En el desarrollo front-end web, JavaScript se utiliza principalmente para el procesamiento de la interfaz de usuario de los navegadores. El desarrollo de la interfaz de usuario es un modelo típico de un solo subproceso basado en eventos, por lo que JavaScript también ha formado el procesamiento asíncrono como el principal paradigma de programación. Pero en aplicaciones complejas y de gran escala, los problemas y las complejidades que genera la programación asincrónica son cada vez más evidentes.
La llegada de Node.js trajo 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 gran simultaneidad y E/S. 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 anidamiento de muchas funciones de devolución de llamada y el orden de las llamadas asíncronas, lo que aumenta la complejidad y dificultad del programa.
Para resolver estos problemas y dificultades, nació fibjs. fibjs es un marco de desarrollo de servidor de aplicaciones diseñado principalmente para el desarrollo de backend web. Se basa en el motor JavaScript de Google v8 y elige una solución de concurrencia diferente de la devolución de llamada tradicional. fibjs usa fibra para aislar la complejidad empresarial causada por las llamadas asincrónicas en la capa del marco, lo que reduce en gran medida la dificultad del desarrollo y reduce 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 asíncrona tradicional, su paradigma de programación síncrona es más legible, simple en lógica y fácil de mantener.
En el siguiente contenido, presentaremos las ventajas y características de fibjs y explicaremos cómo usar sus soluciones de programación síncrona y asíncrona a través de ejemplos.
perfil de fibra
fibjs es un marco de servidor de JavaScript de alto rendimiento basado en el motor v8, principalmente para el desarrollo de back-end web. 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 usa para resolver el problema entre la lógica comercial y el procesamiento de E/S. La fibra es diferente de los conceptos tradicionales, como subprocesos, corrutinas y procesos, es un subproceso ligero a nivel de usuario que puede considerarse como un mecanismo cooperativo multitarea. La fibra puede ejecutar lógica de negocios y operaciones de E/S en diferentes contextos, y administrar internamente los recursos a través de la preasignación y el reciclaje. En comparación con los procesos y subprocesos tradicionales, es más liviano, 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 cooperativa : Fiber es una programación cooperativa que no requiere una programación preventiva por parte del kernel o del sistema operativo, lo que reduce el cambio frecuente de contexto, acelera la ejecución del programa y evita las condiciones de carrera y los bloqueos entre subprocesos.
Ligero : cada fibra solo necesita consumir un pequeño espacio de pila, y se puede crear una gran cantidad de fibras en aplicaciones multiconcurrentes sin causar un uso excesivo de la memoria.
Eficiencia : Fiber 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.
Mediante el uso de fibra, fibjs puede separar la lógica comercial del procesamiento de E/S, encapsulando así las llamadas asincrónicas en llamadas sincrónicas, lo que hace que escribir y mantener el código sea más fácil y más fácil de leer, al tiempo que aprovecha al máximo las ventajas del lenguaje JavaScript.
Programación síncrona en fibjs
En la programación asíncrona, debido al anidamiento de las funciones de devolución de llamada, la legibilidad del código puede ser deficiente y es probable que ocurra el problema del infierno de devolución de llamada, lo que aumenta la dificultad del código y el costo de la depuración. El paradigma de programación síncrona está más en línea con el modo de pensamiento humano, lo que hace que la estructura del código sea más clara, más fácil de leer y más fácil 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, 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, las funciones asincrónicas de los objetos incorporados se pueden llamar directa y sincrónicamente:
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
También puede envolver la función asíncrona a través de util.sync y try...catch, para que la fibra pueda obtener el valor de retorno de la llamada asíncrona, para lograr un efecto síncrono, 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 asíncrona fs.readFile en una función síncrona.Esta función puede devolver datos directamente a través de una llamada síncrona. Este método de llamada síncrona es similar al paradigma de programación JavaScript tradicional, la diferencia es que en fibjs, los hilos no se bloquean, pero los efectos asíncronos se logran a través de fibras.
El principio de 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 sincronización de función de utilidad para convertir una función de devolución de llamada asíncrona en una función de llamada síncrona. Toma 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 síncrona. En la función _wrap, primero se crea un nuevo objeto de evento ev para la programación de subprocesos y espera los resultados de devolución de llamada asíncrona. Luego use el método apply 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 la 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 de evento. Finalmente, de acuerdo con la variable e para decidir si lanzar una excepción o devolver la variable r. Esta función implementa una solución para convertir una función de devolución de llamada asíncrona en una llamada síncrona, lo que puede mejorar la legibilidad y el mantenimiento de la función.
Programación asíncrona en fibjs
En fibjs, la mayoría de los métodos asíncronos (incluidos los métodos de solicitud de E/S y de red, etc.) pueden admitir llamadas síncronas y asíncronas al mismo tiempo, lo que permite a los desarrolladores elegir qué método usar en cualquier momento según sus necesidades de programación.
Tomando fs.readFile() como ejemplo, podemos usar este método de dos maneras:
Modo asincrónico: pase una función de devolución de llamada para procesar el resultado de leer el archivo, 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 enfoque es adecuado para situaciones en las que necesita realizar algunas operaciones después de completar la lectura del archivo.
Modo 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 al leer los datos de valor de retorno del archivo, y no necesitamos esperar a que se ejecute la función de devolución de llamada de la finalización de la lectura del archivo antes de continuar. Este enfoque 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 diferentes métodos según sus necesidades y escenarios de desarrollo. En algunos casos, el código síncrono es más legible, más fácil de mantener y depurar, mientras que en algunos casos, el código asíncrono puede mejorar mejor la capacidad de respuesta y el rendimiento del código.
Sin embargo, también debe prestar atención cuando utilice el método síncrono, ya que en algunos escenarios, este método puede bloquear la fibra actual. Por lo tanto, debemos elegir el método de programación adecuado de acuerdo con las necesidades reales.
en conclusión
En este artículo, presentamos el estilo de programación síncrona de fibjs y las soluciones de programación asíncrona, 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 asíncrono. Al mismo tiempo, también enfatizamos las ventajas de fibjs en el procesamiento de E/S y la gestión de memoria, lo que brinda una gran comodidad para el desarrollo, las pruebas y el mantenimiento.
Finalmente, alentamos a los lectores a explorar fibjs en profundidad y a 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.