{"id":1560,"date":"2014-03-03T10:45:09","date_gmt":"2014-03-03T09:45:09","guid":{"rendered":"http:\/\/complexitymaze.com\/?p=1560"},"modified":"2014-03-03T10:45:09","modified_gmt":"2014-03-03T09:45:09","slug":"javascript-promises-a-comparison-of-libraries","status":"publish","type":"post","link":"https:\/\/complexitymaze.com\/?p=1560","title":{"rendered":"JavaScript Promises \u2013 a comparison of libraries"},"content":{"rendered":"<p>In my <a href=\"http:\/\/qed.dk\/poul-foged\/2014\/02\/21\/javascript-promises-ryd-op-de-asynkrone-kald\/\" target=\"_new\" rel=\"noopener\">previous<\/a> post in Danish I looked at how to perform asynchronous calls by using promises. Now the time has come to pick which library that fits the next project.<\/p>\n<p>There is a lot of variants and the spread is huge. One search for promise via the node package manager <a href=\"https:\/\/www.npmjs.org\">npmjs.org<\/a> gave 1150 libraries which either provides or are dependent on promises. Of these I have picked 12 different libraries to look at, all are open source and all offer a promise-like structure.<\/p>\n<p><b>Updates:<\/b> <\/p>\n<ul>\n<li>2014\/03\/06 &#8211; Fixed a few misspellings (@rauschma via Twitter)<\/li>\n<li>2014\/03\/07 &#8211; Removed raw sizes, since they did&#8217;nt make much sense (@x-skeww via Reddit)<\/li>\n<li>2014\/03\/07 &#8211; Added that catiline uses lie underneath. (@CWMma via Twitter)<\/li>\n<li>2014\/03\/07 &#8211; Added clarification on what the test does. (@CWMma via Twitter)<\/li>\n<\/ul>\n<p>The API across the libraries are almost alike, so I&#8217;ve decided to look at:<\/p>\n<p><i>Features<\/i><br \/>\nWhat kind of generic promise related features does each library offer?<\/p>\n<p><i>Size<\/i><br \/>\nAnd I&#8217;m thinking mostly browsers here &#8211; how many extra bytes will this add to my site?<\/p>\n<p><i>Speed<\/i><br \/>\nHow fast are the basic promise operations in the library? You would expect that these will execute many times so this is important.<\/p>\n<p>&nbsp;<\/p>\n<h3>The libraries<\/h3>\n<p>\nFirst an overview of the selected candidates, their license and author. Note that the name is linking to the source of the library (typical Github).\n<\/p>\n<p>&nbsp;<\/p>\n<table style=\"font-size: 13px;background-color: #eee\">\n<tbody>\n<tr>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\"><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\">License<\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\">Author<\/td>\n<td style=\"font-weight: bold;border-color: #FFF\">Note<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/petkaantonov\/bluebird\">Bluebird<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Petka Antonov<\/td>\n<td style=\"border-color: #FFF\">\nLoaded with features and should be one of the fastest around and with special empathizes on error handling via good stack traces. Features can be toggled via custom builds.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/calvinmetcalf\/catiline\">Catiline<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Calvin Metcalf<\/td>\n<td style=\"border-color: #FFF\">\nMostly designed for handling of web workers but contains a promise implementation. Uses lie underneath.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/jakearchibald\/es6-promise\">ES6 Promise polyfill<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Jake Archibald<\/td>\n<td style=\"border-color: #FFF\">\nBorrows code from RSVP, but implemented according to the ECMAScript 6 specification.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"http:\/\/jquery.com\">jQuery<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">\u00a0The jQuery Foundation<\/td>\n<td style=\"border-color: #FFF\">\nClassic library for DOM-manipulation across browsers.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/Obvious\/kew\">kew<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/www.apache.org\/licenses\/LICENSE-2.0.html\">Apache 2.0<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">\u00a0The Obvious Corporation<\/td>\n<td style=\"border-color: #FFF\">\nI&#8217;m guessing it is pronounced &#8216;Q&#8217;, can be considered as a optimized edition of Q but with a smaller feature set.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/calvinmetcalf\/lie\">lie<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Calvin Metcalf<\/td>\n<td style=\"border-color: #FFF\"><\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/gist.github.com\/RubaXa\/8501359\">MyDeferred<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">RubaXa<\/td>\n<td style=\"border-color: #FFF\">Small Gist style implementation<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/cho45\">MyPromise<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">cho45@lowreal.net<\/td>\n<td style=\"border-color: #FFF\">Small Gist style implementation<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/kriskowal\/q\">Q<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Kris Kowal<\/td>\n<td style=\"border-color: #FFF\">\nWell known implementation, a light edition of it can be found in the popular AngularJS framework from Google.<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/tildeio\/rsvp.js\">RSVP<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Tilde<\/td>\n<td style=\"border-color: #FFF\"><\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"https:\/\/github.com\/cujojs\/when\">when<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/opensource.org\/licenses\/MIT\" target=\"_blank\" rel=\"noopener\">MIT<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">cujoJS<\/td>\n<td style=\"border-color: #FFF\"><\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\"><a href=\"http:\/\/yuilibrary.com\/\">Yui<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\"><a href=\"http:\/\/yuilibrary.com\/license\" target=\"_blank\" rel=\"noopener\">BSD<\/a><\/td>\n<td style=\"border-color: #FFF;text-align: center\">Yahoo!<\/td>\n<td style=\"border-color: #FFF\">Yahoo&#8217;s library for DOM-manipulation across browsers.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h3>Features<\/h3>\n<p>The following is a look at the library feature set, looking only at features directly linked to promises:<\/p>\n<p>&nbsp;<\/p>\n<table style=\"font-size: 13px;background-color: #eee\">\n<tbody>\n<tr>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\"><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#promises\">Promises\/A+<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#progression\">Progression<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#delayed\">Delayed promise<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#parallel\">Parallel synchronization<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#webworkers\">Web Workers<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#cancellation\">Cancellation<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#generators\">Generators<\/a><\/td>\n<td style=\"font-weight: bold;border-color: #FFF;text-align: center\"><a href=\"#jquery\">Wrap jQuery<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">Bluebird<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 (+389 B)<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 (+615 B)<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 (+272 B)<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 (+396 B)<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 (+276 B)<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713 <\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">Catiline<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">ES6 Promise polyfill<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">JQuery<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">kew<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">lie<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">MyDeferred<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">MyPromise<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">Q<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">RSVP<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">when<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<\/tr>\n<tr>\n<td style=\"font-weight: bold;border-color: #FFF\">Yui<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">\u2713<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<td style=\"border-color: #FFF;padding: 5px;text-align: center\">&#8211;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><sup><br \/>\nThe numbers in parenthesis by Bluebird is the additional size in bytes each feature will add.<\/sup><\/p>\n<p><i id=\"promises\">Promises\/A+<\/i><br \/>\nIs the <a href=\"http:\/\/promises-aplus.github.io\/promises-spec\/\" target=\"_new\" rel=\"noopener\">Promises\/A+ specification implemented<\/a>?<\/p>\n<p><i id=\"progression\">Progression<\/i><br \/>\nAre methods provided for notification on status on asynchronous tasks before the task is completed?<\/p>\n<p><i id=\"delayed\">Delayed promise<\/i><br \/>\nCan you create a promise that is resolved after a specified delay?<\/p>\n<p><i id=\"parallel\">Parallel synchronization<\/i><br \/>\nAre there methods for synchronization of multiple operations, can we get a resolved promise when a bunch of other promises are resolved?<\/p>\n<p><i id=\"webworkers\">Web Workers<\/i><br \/>\nCan asynchronous code be executed via a web worker &#8211; pushed to a separate execution thread?<\/p>\n<p><i id=\"cancellation\">Cancellation<\/i><br \/>\nCan promise execution be stopped before it is finished?<\/p>\n<p><i id=\"generators\">Generators<\/i><br \/>\nAre coming functions around JavaScript generators supported?<\/p>\n<p><i id=\"jquery\">Wrap jQuery<\/i><br \/>\nCan promises produced by jQuery be converted to this library&#8217;s promises?<\/p>\n<p>&nbsp;<\/p>\n<h3>Size<\/h3>\n<p>Every library have been minified via Googles <a href=\"http:\/\/closure-compiler.appspot.com\/home\">Closure compiler<\/a>. All executed on &#8216;Simple&#8217; to prevent any damaging changes. For libraries that support custom builds I have picked the smallest configuration that still supports promises. The result is including compression in the http-stack, so its actually the raw number of bytes one would expect that the application is added when using each library:<\/p>\n<p>&nbsp;<\/p>\n<div style=\"width: 100%;clear: both;float: left;margin: -20px 20px 20px\">\n<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/complexitymaze.poulfoged.com\/wp-content\/uploads\/2014\/03\/minified-and-compressed.png\" style=\"border:none;\" alt=\"Minified and compressed\" width=\"700\" height=\"542\" class=\"aligncenter size-full wp-image-1575\" srcset=\"https:\/\/complexitymaze.com\/wp-content\/uploads\/2014\/03\/minified-and-compressed.png 700w, https:\/\/complexitymaze.com\/wp-content\/uploads\/2014\/03\/minified-and-compressed-300x232.png 300w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/div>\n<h3>Speed<\/h3>\n<p>The speed has been measured via the site <a href=\"jsperf.com\">jsPerf<\/a> which gives the option to execute the same tests across a lot of different browsers and platforms including mobile and tablets. <em><a href=\"http:\/\/jsperf.com\/promise-comparisons\/91\">The test<\/a> creates a new promise with each library and measures how much latency is imposed on execution of the asynchronous block (see more detailed explanation <a href=\"http:\/\/calvinmetcalf.com\/post\/61761231881\/javascript-schedulers\" target=\"_new\" rel=\"noopener\">here<\/a>)<\/em>. Note that the test was not created by me, but a lot of fantastic people (current version is 91). The numbers are average across platforms:<\/p>\n<p>&nbsp;<\/p>\n<div style=\"width: 100%;clear: both;float: left;margin:-20px 20px 20px\">\n<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/complexitymaze.poulfoged.com\/wp-content\/uploads\/2014\/03\/operations-per-second4.png\" style=\"border:none;\" alt=\"Operations per second\" width=\"700\" height=\"542\" class=\"aligncenter size-full wp-image-1574\" srcset=\"https:\/\/complexitymaze.com\/wp-content\/uploads\/2014\/03\/operations-per-second4.png 700w, https:\/\/complexitymaze.com\/wp-content\/uploads\/2014\/03\/operations-per-second4-300x232.png 300w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/>\n<\/div>\n<h3>Conclusion<\/h3>\n<p>Over half of the worlds websites already uses jQuery. If you have worked with promises in jQuery, you quickly find that they are inadequate.<br \/>\nI have previously had problems with failing code that doesn&#8217;t reject the promise on error as you would expect, but where the error still bubbles up and ends up being a global browser error. The promise specification dictates that errors should be caught and the promise rejected, which is not what happens in jQuery.<\/p>\n<p>So if you today have a site based on jQuery, the obvious choice is to pick one of the libraries that offers conversion from jQuery&#8217;s unsafe promises to one of the more safe kind. If size is a priority either Q or when are good suggestions, loaded with features and at a decent speed.<\/p>\n<p>If you are less worried about size, Bluebird is a better choice. The modularity makes it easy to toggle features and it has a significant test suite that covers performance on a lot of other aspects than the single one covered by this post.<\/p>\n<p>If performance is essential, kew is a good bet. A team has picked up Q and looked into lowering its resource requirements. This has resulted in a light weight but very fast library.<\/p>\n<p>If you are looking for a more limited solution with good speed and without big libraries, the ES6 Promise polyfill is a good choice &#8211; then in the long term when the browsers catch up, the library can be removed completely.<\/p>\n<p><em>This post is also available in Danish at <a href=\"http:\/\/qed.dk\/poul-foged\/2014\/03\/03\/en-sammenligning-af-JavaScript-promise-biblioteker\/\">QED.dk<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous post in Danish I looked at how to perform asynchronous calls by using promises. Now the time has come to pick which library that fits the next project. There is a lot of variants and the spread is huge. One search for promise via the node package manager npmjs.org gave 1150 libraries [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1560","post","type-post","status-publish","format-standard","hentry","category-misc"],"_links":{"self":[{"href":"https:\/\/complexitymaze.com\/index.php?rest_route=\/wp\/v2\/posts\/1560","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/complexitymaze.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/complexitymaze.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/complexitymaze.com\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/complexitymaze.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1560"}],"version-history":[{"count":0,"href":"https:\/\/complexitymaze.com\/index.php?rest_route=\/wp\/v2\/posts\/1560\/revisions"}],"wp:attachment":[{"href":"https:\/\/complexitymaze.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/complexitymaze.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/complexitymaze.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}