I have developed which is a fast Promise library. It is inspired by . The library is not only a exercise but a production-ready library that implements the Promise A+ standard, and does so faster than . [Aigle](https://github.com/suguru03/aigle) [Bluebir](https://github.com/petkaantonov/bluebird)d benchmark Bluebird What are Promises? Before explaining it, I would like to give basic information about Promises. A Promise can have three states: , and . Once the state goes to another state from , the state cannot change again. pending fulfilled rejected pending Besides, Promises must always resolve asynchronously, this is one of the most important things. Promise(resolve => resolve(1)) // synchronously.then(num => {// called asynchronously}); new Best practices for high-performance libraries When I develop libraries, I always follow these three principles. Avoid creating unnecessary variables, functions and instances Avoid executing unnecessary functions Deal with asynchronous function smartly Avoid creating unnecessary variables, functions and instances Following this principle helps avoiding unnecessary memory allocations. For example, sum(array) { array.reduce( iterator(result, num) { result num;});} function return function return + sum([1, 2, 3]); // 6 When is called, the function is always created. It is one of unnecessary memory allocations. The code is rewritten to follow next example. sum iterator iterator(result, num) { result num;} function return + sum(array) { array.reduce(iterator);} function return sum([1, 2, 3]); // 6 The code avoids making unnecessary functions. Next is another extra example of memory allocation. get(type) { array []; object {}; number 0; string ''; (type) { 'array' array; 'object' object; 'number' number; 'string' string;}}get('string'); function const = const = const = const = switch case : return case : return case : return case : return In this case, is the only required variable. , and are unnecessary. The code is rewritten as below, string array object number get(type) { (type) { 'array' []; 'object' {}; 'number' 0; 'string' '';}}get('string'); function switch case : return case : return case : return case : return There is not a big difference between the examples, but if instances or functions are created in the function, it would make big difference. Avoid executing unnecessary functions For example, when creating APIs, it is necessary to check the request parameters. api(req, res) { { id } req.body; (**!**isNumber(id)) { res.sendStatus(400);}innerFunc(id).then(...). (...)} function const = if return catch isNumber(id) { id 'number';} function return typeof === innerFunc(id) { (**!**isNumber(id)) { Promise.reject( Error('error'));}...} function if return new When implementing APIs, it is preferable to check the arguments in inner functions because the function might be called from other functions. However, when implementing libraries, the function doesn’t need to check the arguments. Before executing inner functions, the arguments are already checked, so it isn’t necessary to check them again in inner functions. Deal with asynchronous function smartly I would like to explain this concept with examples. Bluebird What makes Bluebird fast? If you open library code, you will see parameters. But the is not so important. has roughly two states: or not. The big difference in handling is between the two states. Bluebird bitField bitField Bluebird pending If the state is pending: Bluebird( executor(resolve) {// called synchronouslysetTimeout( timer() {resolve(1); }, 10);}).then( onFulfilled(value) { }); new function function // called asynchronously function // called asynchronously This execution order is, Make a parent instance of when new is called Bluebird Bluebird Execute executor Execute . makes a child instance of then then Bluebird Execute resolve Execute onFulfilled When is called, . At that time, is not called yet, so the parent’s state is . When the state is , . After that, asynchronously by . And then, .When state is , a child instance is linked to parent instance. After is called, is called. It is very simple. then a child instance is created resolve pending pending the child instance is linked to the parent instance as a child [resolve](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L513) is called setTimeout [onFulfilled](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L703-L710) is called with the result pending resolve onFulfilled If state is not pending: Bluebird( executor(resolve) {resolve(); }).then( onFulfilled(value) { }); new function // called synchronously function // ensured asynchronously The execution order is Make a parent instance of when new is called Bluebird Bluebird Execute executor Execute resolve Execute . makes a child instance of then then Bluebird Execute onFulfilled When is called, the parent’s state is already not . In this case, if is called without anything, the function is executed synchronously. For that reason, the library needs to . Before calling the function, is a and this . The is on Node.js. And then .When a state is not , is set to a , and then queued functions are executed by asynchronous functions. then pending onFulfilled call an asynchronous function onFulfilled set to [queue](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L88) [schedule](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L159) function is called schedule setImmediate [setImmediate](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L144) calls all queued functions asynchronously pending onFulfilled queue You might be wondering why is set to a . This is the smartest idea in . onFulfilled queue Bluebird How to handle the asynchronous function smartly I would like to explain it with this example. Bluebird.resolve(1) .then(num console.log(num)); Bluebird.resolve(2) .then(num console.log(num)); Bluebird.resolve(3) .then(num console.log(num)); // synchronously => // asynchronously // synchronously => // asynchronously // synchronously => // asynchronously If a is not used, an asynchronous function is called three times. But if a is used, the function executes all queued functions at once.I’m not sure if the gives a big benefit or not. But I think why is fast is because of simplicity. queue queue bitField Bluebird What makes Aigle fast? I have just followed these important principles, Avoid creating unnecessary variables, functions and instances Avoid executing unnecessary functions Deal with asynchronous function smartly If you follow them, you will be able to make good libraries. I made a to check performance between and . The benchmark result is here. benchmark Aigle Bluebird Node v6.9.1 Aigle v0.5.0 Bluebird v3.5.0 Aigle vs Bluebird has very simple implementation, therefore it is faster than . If you are interested in , I would like you to contribute to it. Aigle Bluebird Aigle Intended for production environment The most important part is dependency. In , every promise instance has to be an instance of . When the instance is checked, function is called. But only checks if the instance is made by the class or not. So if many versions are used, will be slowed down.The key to avoiding losing performance is to have same dependency. has dependency, therefore every instance is extended by same class. will keep high performance. aigle-core Bluebird Bluebird instanceof Bluebird current **Bluebird** Bluebird Aigle aigle-core Aigle AigleCore Aigle I would like to show . the benchmark example $ npm listaigle-benchmark@0.0.0├─┬ aigle@0.5.0 <- aigle@0.5.0 has aigle-core@0.2.0│ └── aigle-core@0.2.0├─┬ benchmark@2.1.3│ └── platform@1.3.3├── bluebird@3.5.0├── lodash@4.17.4├── minimist@1.2.0└─┬ promise-libraries@0.3.0├── aigle@0.4.0 <- aigle@0.4.0 has aigle-core@0.2.0 too└── bluebird@3.4.6 As you can see, different dependencies have same sub-dependencies. When is used, the is shared. aigle aigle-core aigle@0.4.0 aigle-core Node v6.9.1 v0.4.0, v0.5.0 Aigle v3.4.6, v3.5.0 Bluebird $ node --expose_gc . -t then======================================[Aigle] v0.5.0[Bluebird] v3.5.0======================================[promise:then:same] Preparing...--------------------------------------[promise:then:same] Executing...[1] "aigle" 180μs[1.00][1.00][2] "bluebird" 341μs[0.526][1.90]======================================[promise:then:diff] Preparing...--------------------------------------[promise:then:diff] Executing...[1] "aigle" 178μs[1.00][1.00][2] "bluebird" 506μs[0.352][2.84] was using same versions, and used child instances of different versions. never slows down even if the versions are mixed. promise:then:same promise:then:diff Aigle Conclusion If you follow the three important principles, you will make a fast library. Also has many functions inspired by and . If you still use callback style, I would like to encourage you using . If I contribute to and communities, I would be happy as a contributor. Aigle [Async](https://github.com/caolan/async) [Neo-Async](https://github.com/suguru03/neo-async) Aigle Node.js JavaScript Reference [Aigle](https://github.com/suguru03/aigle) [Bluebird](https://github.com/petkaantonov/bluebird) MDN