Guide Development Guide

What is fibjs?

fibjs is an application server development framework designed primarily for web back-end development. It is built on the Google v8 JavaScript engine and chooses a different concurrency solution than traditional callback. Fibjs uses fiber to isolate the business complexity caused by asynchronous calls at the framework layer, which greatly reduces the development difficulty and reduces the performance problems caused by frequent asynchronous processing in user space.

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

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

Back to the original, agile development

Fibjs uses fiber in 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, to complete the same work, 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 pursue simplicity, you can even write 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 brought by two different programming styles. Less code will bring fewer errors, and as the code decreases, the logic of the code becomes clearer, whether it is development or maintenance, it will benefit from it.

Embrace high energy

Although we can easily increase the response speed by expanding the server, performance should still be one of the important basis for choosing a development framework. With the introduction of ES7, async was introduced to 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 brought 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, the results of this code run are 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 to process the async function call and return. We also found this in the actual testing of some server applications. And this sharp decline in performance is completely unacceptable.

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

Flexible choice of paradigm without being kidnapped

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 can flexibly switch between synchronous style and asynchronous style.

Whether it is callback or async, there is a fatal flaw, that is contagious. 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. In the early stage of the project, we chose memory as the session data storage. At this time, we can use sync to read and store data directly, 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 the session-related operations to async mode.

In theory, we can modify each function in turn to make them conform to the requirements of the functions it depends on, but this requires us to fully understand all the modules and have the ability to modify them. This is completely impossible when 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. Thereby causing performance disasters.

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

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 at a minimum development cost, effectively avoiding the disasters caused by paradigm contagion.

Start to experience

Are you ready to start a pleasant development experience? So, start with the installation.

👉 【 Installation and Operating Environment