Guide Development Guide

What is fibjs?

fibjs is an application server development framework designed mainly for web backend development. It is based on the Google v8 JavaScript engine and chooses a different concurrent solution than the traditional callback. Fibjs uses fiber to isolate the business complexity caused by asynchronous calls at the framework layer, greatly reducing the development difficulty and reducing the performance problems caused by frequent asynchronous processing in user space.

For historical reasons, JavaScript is mainly used for UI processing in browsers. UI development is a typical single-threaded event-driven model, so JavaScript has also formed asynchronous programming as the main programming paradigm.

With the success of JavaScript, more and more people are beginning to apply JavaScript to other scenarios. At the same time, people are increasingly finding that asynchronous processing is not the most appropriate choice in many scenarios.

Back to true, agile development

Fibjs uses fiber at the framework layer to isolate the business complexity caused by asynchronous calls, and encapsulates the asynchronous processing of io into more intuitive synchronous calls. Engineers only need to write code according to the usual synchronous business logic to enjoy the benefits of asynchronous processing Great convenience.

The following code is taken from the documentation of the mysql module:

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
conn.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!'); }); }); }); });

In fibjs, the same work is done, the code is as follows:

1 2 3 4 5 6
conn.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!');

If you're after simplicity, you can even write the code like this:

1 2 3 4
conn.trans(() => conn.execute('INSERT INTO log SET data=?', 'Post ' + conn.execute('INSERT INTO posts SET title=?', title).insertId + ' added')); console.log('success!');

We can clearly compare the differences between two different programming styles. Fewer code leads to fewer errors, and as the code decreases, the logic of the code becomes clearer, and it benefits from both development and maintenance.

Embrace High Energy

Although we can easily increase the response speed by expanding the server, performance should still be one of the important reasons for choosing a development framework. With the introduction of ES7, async was introduced into JavaScript as a new asynchronous development model. However, when we enjoy the synchronization style brought by async, we also have to face its impact on performance.

We can use a piece of test code to compare the performance differences caused by different programming styles:

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 39
var 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();

Under the latest v8 v6.7.192, this code runs as follows:

1 2 3
async: 5.276ms callback: 0.117ms sync: 0.038ms

We can clearly know from the test results that when async is widely used in the project, the server will spend a lot of time processing the call and return of async functions. We also found this in actual testing of some server-side applications. And the sharp drop in performance is completely unacceptable.

Because fibjs uses fiber, it can make full use of the features of the JavaScript language itself, and maximize the superior performance of v8. Engineers can easily maximize server performance.

Flexible choice of paradigm without being abducted

Choosing to use fibjs does not mean that you must use a synchronous development style. In fact, fibjs supports any asynchronous programming paradigm you have seen, and has the flexibility to switch between synchronous and asynchronous styles.

Whether it is callback or async, there is a fatal flaw, which is contagion. As long as a function is callback or async, all other functions that depend on it must be callback or async. This will bring huge development costs in large-scale software development.

Take a simple server development scenario as an example. At the beginning of the project, we chose memory as the session data storage. At this time, we can directly read and store data using the sync method, and develop a complete business based on this. With the development of business scale, we need to store session data in redis or mongodb. At this time, we need to modify session related operations to async mode.

In theory, we can modify each function in turn to make them meet the requirements of the dependent function, but this requires us to fully understand all modules and have the ability to modify them. This is completely impossible during multi-person collaborative development or when using third-party modules.

Therefore, all common modules need to provide both sync and async interfaces to balance the balance between asynchronous and performance. More ordinary developers will choose to provide only async interface. This can lead to performance disasters.

In fibjs, you can easily solve similar problems and avoid explicit asynchronous and uncontrolled transmission:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var 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 can use util.sync to turn callback or async functions into sync functions and call them directly. In this way, we can easily integrate modules of different programming paradigms and transform them into sync paradigms with minimal development costs, effectively avoiding the disaster brought by paradigm infection.

Start experience

Ready to start an enjoyable development experience? So let's start with the installation.

👉 [ installation and operation environment ]