Guide Development Guide

What is fibjs?

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

For historical reasons, JavaScript is mainly used for browser UI processing. UI development is a typical single-threaded event-driven mode, so JavaScript also forms 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.

Return to the original, agile development

Fibjs uses fiber in the framework layer to isolate the business complexity brought 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, which can be enjoyed by asynchronous processing. Great convenience.

The following code is taken from the documentation for 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, do the same thing, 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 are pursuing 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 the two different programming styles. Fewer code leads to fewer errors, and as the code is reduced, the logic of the code is clearer, and both development and maintenance will benefit.

Embrace high energy

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

We can use a piece of test code to compare performance differences between 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 result of this code is as follows:

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

We can clearly see from the test results that when async is widely used in a project, the server will spend a lot of time processing the call and return of the async function. We also found this in the actual testing of some server applications. And this sharp decline in performance is totally unacceptable.

Fibjs uses fiber to take full advantage of the features of the JavaScript language and maximize the performance of v8. Engineers can easily maximize the performance of their servers.

Flexible choice of paradigm without being kidnapped

Choosing to use fibjs doesn't mean you have to use a synchronous development style. In fact, fibjs supports any asynchronous programming paradigm you've ever 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 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. At the beginning of the project, we chose memory as the session data store. At this point, we can use the sync method to directly read and store data, and based on this, develop a complete business. As the business scale grows, we need to store the session data in redis or mongodb. At this point, we need to modify the session-related operations to async mode.

In theory, we can modify each function in turn to match the requirements of the function it depends on, but this requires us to fully understand all the modules and have the ability to modify them. This is completely impossible to do 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 normal developers will choose to only provide the async interface. This causes a performance disaster.

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

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 a callback or async function into a sync function and call it directly. In this way, we can easily integrate modules of different programming paradigms and transform them into sync paradigms with minimal development cost, effectively avoiding the disaster caused by paradigm infection.

Start the experience

Ready to start a pleasant development experience? So, let's start with the installation.

👉 [ Installation and operation environment ]