¿Qué es fibjs?
fibjs es un marco de desarrollo de servidor de aplicaciones diseñado para el desarrollo web backend. Está construido sobre el motor JavaScript V8 de Google y utiliza una solución de concurrencia diferente a las devoluciones de llamada tradicionales. fibjs utiliza fibra (fibra) para aislar la complejidad empresarial causada por llamadas asincrónicas a nivel de marco, lo que reduce en gran medida la dificultad de desarrollo y reduce los problemas de rendimiento causados por el procesamiento asincrónico frecuente en el espacio del usuario.
Por razones históricas, JavaScript se utiliza principalmente para manejar la interfaz de usuario del navegador. El desarrollo de la interfaz de usuario es un modelo típico basado en eventos de un solo subproceso, por lo que JavaScript ha ido formando gradualmente el procesamiento asincrónico como el principal paradigma de programación.
Con el éxito de JavaScript, cada vez más personas comienzan a aplicar JavaScript a otros escenarios. Al mismo tiempo, la gente es cada vez más consciente de que, en muchos escenarios, el procesamiento asincrónico no es la opción más adecuada.
Regreso a la naturaleza, desarrollo ágil
fibjs utiliza fibra (fibra) a nivel de marco para aislar la complejidad empresarial causada por llamadas asincrónicas y encapsula el procesamiento de E / S asincrónicas en llamadas sincrónicas más intuitivas. Los ingenieros solo necesitan escribir código de acuerdo con la lógica empresarial síncrona habitual y disfrutar de la gran comodidad que ofrece el procesamiento asincrónico.
El siguiente código está tomado de la documentación del módulo mysql:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32conn.beginTransaction(err => {
if (err) {
throw err;
}
conn.query('INSERT INTO posts SET title=?', title,
(error, results, fields) => {
if (error) {
return conn.rollback(() => {
throw error;
});
}
var log = 'Post ' + results.insertId + ' added';
conn.query('INSERT INTO log SET data=?', log,
(error, results, fields) => {
if (error) {
return conn.rollback(() => {
throw error;
});
}
conn.commit((err) => {
if (err) {
return conn.rollback(() => {
throw err;
});
}
console.log('success!');
});
});
});
});
En fibjs se hace el mismo trabajo, el código es el siguiente:
1
2
3
4
5
6conn.trans(() => {
var result = conn.execute('INSERT INTO posts SET title=?', title);
var log = 'Post ' + results.insertId + ' added';
conn.execute('INSERT INTO log SET data=?', log);
});
console.log('success!');
Si buscas simplicidad, incluso puedes escribir el código así:
1
2
3
4conn.trans(() => conn.execute('INSERT INTO log SET data=?',
'Post ' + conn.execute('INSERT INTO posts SET title=?', title).insertId +
' added'));
console.log('success!');
A través de la comparación, podemos ver claramente las diferencias que aportan los diferentes estilos de programación. Menos código significa menos errores y con menos código, la lógica del código se vuelve más clara. En este caso, se beneficiarán tanto los trabajos de desarrollo como los de mantenimiento.
Abraza la alta energía
Aunque es relativamente fácil escalar un servidor para mejorar la capacidad de respuesta, el rendimiento sigue siendo una de las consideraciones importantes al elegir un marco de desarrollo. Con la introducción de ES7, async se introdujo en JavaScript como un nuevo modelo de desarrollo asincrónico. Sin embargo, si bien disfrutamos del estilo de programación síncrono que aporta async, también debemos afrontar su impacto en el rendimiento.
Para comparar las diferencias de rendimiento que aportan los diferentes estilos de programación, podemos utilizar el siguiente código de prueba:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39var count = 1000;
async function test_async(n) {
if (n == count)
return;
await test_async(n + 1);
}
function test_callback(n, cb) {
if (n == count)
return cb();
test_callback(n + 1, () => {
cb();
});
}
function test_sync(n) {
if (n == count)
return;
test_sync(n + 1);
}
async function test() {
console.time("async");
await test_async(0);
console.timeEnd("async");
console.time("callback");
test_callback(0, () => {
console.timeEnd("callback");
});
console.time("sync");
test_sync(0);
console.timeEnd("sync");
}
test();
En la última versión 8, los resultados de ejecución de este código son los siguientes:
1
2
3async: 0.539ms
callback: 0.221ms
sync: 0.061ms
A partir de los resultados de la prueba, podemos ver claramente que cuando se usa ampliamente asíncrono, el servidor dedicará mucho tiempo a procesar las llamadas y devoluciones de funciones asíncronas. También encontramos esto en algunas pruebas reales de aplicaciones del lado del servidor. Sin embargo, esta drástica caída del rendimiento es completamente inaceptable.
Por el contrario, fibjs utiliza tecnología de fibra, aprovecha al máximo las características del propio lenguaje JavaScript y maximiza el rendimiento superior del motor V8. Los ingenieros pueden maximizar fácilmente el rendimiento del servidor.
Elige paradigmas con flexibilidad sin dejarte secuestrar
Elegir utilizar fibjs no significa que deba utilizar un estilo de desarrollo sincrónico. De hecho, fibjs admite varios paradigmas de programación asincrónica con los que está familiarizado y puede cambiar de manera flexible entre estilos sincrónicos y asincrónicos.
Sin embargo, ya sean funciones de devolución de llamada o asíncronas, tienen un defecto fatal: el contagio. Si una función es una función de devolución de llamada o asíncrona, entonces todas las demás funciones que dependen de ella también deben ser funciones de devolución de llamada o asíncronas. En el desarrollo de software a gran escala, esto resultará en enormes costos de desarrollo.
Tomemos como ejemplo un escenario de desarrollo de servidor simple. Al comienzo del proyecto, elegimos almacenar los datos de la sesión en la memoria, en este momento podemos leer y almacenar los datos directamente mediante sincronización y desarrollar funciones comerciales completas en base a esto. A medida que se expande la escala empresarial, necesitamos almacenar los datos de la sesión en Redis o MongoDB, y en este momento debemos cambiar las operaciones relacionadas con la sesión al modo asíncrono.
En teoría, podemos modificar cada función una por una para que cumplan con los requisitos de las funciones dependientes, pero esto requiere que comprendamos completamente todos los módulos y tengamos la capacidad de modificarlos. Esto es casi imposible cuando varias personas desarrollan en colaboración o utilizan módulos de terceros.
Por lo tanto, en todos los módulos comunes, se deben proporcionar interfaces tanto síncronas como asíncronas para equilibrar la relación entre asincronía y rendimiento. Los desarrolladores comunes generalmente optan por proporcionar solo interfaces asincrónicas, lo que genera problemas de rendimiento.
En fibjs puedes resolver fácilmente problemas similares y evitar la propagación incontrolada de asíncrono explícito:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var util = require('util');
function session_get(sid) {
return sdata;
}
async function async_session_get(sid) {
return sdata;
}
function callback_session_get(sid, cb) {
cb(null, sdata);
}
data = session_get(sid);
data = util.sync(async_session_get)(sid);
data = util.sync(callback_session_get)(sid);
fibjs proporciona la función util.sync, que puede convertir funciones de devolución de llamada o funciones asincrónicas en funciones sincrónicas y llamarlas directamente. De esta manera, podemos integrar fácilmente módulos de diferentes paradigmas de programación y minimizar los costos de desarrollo, transformándolos en paradigmas sincronizados, evitando efectivamente el desastre causado por el contagio de paradigmas.
Empieza a experimentar
¿Estás listo para tener una gran experiencia de desarrollo? Entonces, comencemos con la instalación.