Cancellable promise

I write a lot of promise functions everyday. Promise is very useful in many ways, especially  to handle nested callbacks and avoid callback hells. If you have used Promise long enough, you will probably know that Promise is not lazy and also not cancellable. Once you make a promise, you have to stick with it. But for my experience, Promise cancel is necessary sometime, especially when  the promise may take a long time and you want to let user cancel it, or you want to ignore all the chaining callbacks of the promise..

Promise cancellation does not make into ES6 standard yet, and the specification is being discussed here. When a promise is cancelled, it will propagate to the farthest pending promises and reject these promises with a the cancel reason or CancellationError. There are a few promise library that supports cancellation already like BlueBird or Google Closure. But until the spec is approved and you don’t want to bring in these library, can we cannel a promise? The answer is yes, we can do this with Promise.defer and Promise.race.

First of all, let see Promise.defer: Promise.defer return a deferred object. The deferred object is like a promise controller, it allows you to resolve or reject the promise. A promise can’t change the state by itself, only the executor can resolve or reject a promise. You can think deferred like inverse the control outside of the promise itself. Deferred is not a Promises/A+ standard, but you can easily implement with pure javascript. I am going to borrow the code from BlueBird.

What’s about Promise.race? Promise.race takes an array of promises and return a promise that resolve or reject with the value of the earliest promise in the array. This is ES6 standard and a very cool method, you can do a lot of interesting things with it. For example, below is an implementation of time in promise using Promise.race

Now you know deferred and Promise.race, the idea of cancellable promise is actually very simple: it’s a race between the original promise and a deferred. If you cancel, you reject the deferred promise and therefore reject the chain. If you just let it finishes, it will use the resolved result or rejected error from the original promise. Below is a prototype implementation.

Now you can use cancellablePromise to create a promise then cancel it whenever you want.

You can edit the function to throw out a custom Error class and catch it to handle the cancellation correctly. Just a kindly reminder that the above code may not be bug-freed, so be very careful but if you find any problem just let me know :D

Promise chain in Javascript

Promise is very useful in Javascript to eliminate callback hell, but in some case writing promise still seems lengthy. It is very common for me to have a pattern like below

Basically, i want to get the result of the current promise and call an immediate function which returns another promise and so on. It would be great if we can reduce the callback part in the promise and can just use method chaining. (Note: This can be also solved very nicely with generator, but i want to try something new.)

Of course the above code will fail immediately because it will try to call an undefined function on the returned promise. It is like underscore chain function. What if we can catch up all the functions and replay it as promise.
After some help from Google, It turns out that ES6 Proxy can help you to achieve promising chaining. I do a proof of concept implementation of the idea so you can use chain() to chain promise results. Chain will create a Proxy and collect all the called function and when finally() is called, it will replay all the called functions to the promise and return another promise. The code will now look like this with promise chaining:

Now the code just looks like regular  chaining  code. You can also use this with coroutine library like co or Bluebird because it also returns a promise. Pretty cool, huh!

Just a note for you that this implementation is purely for testing and for sure it has a lot of bug, don’t use it for real. Also a side note that Proxy is not yet available in node.js or io.js yet (sigh …), and only Firefox and Internet Explorer 12 support Proxy now. Proxy can’t also be polyfilled due to the limitation of ES5.

Being helpful is not easy

Lesson learnt from being helpful

  • You can’t help anyone if you don’t know about the problem they are having.
  • You can’t help anyone if you don’t really want to help them.
  • And most importantly, you can’t help anyone if they don’t need your help, no matter how helpful you are :)

Broken-Windows Theory

From Wikipedia:

The broken windows theory is a criminological theory of the norm-setting and signaling effect of urban disorder and vandalism on additional crime and anti-social behavior. The theory states that maintaining and monitoring urban environments in a well-ordered condition may stop further vandalism and escalation into more serious crime.

The theory simply says if a window is broken, it is likely the rest of the windows will be broken soon. The environment really affects the behavior of people within it. The theory is widen applied in New York city, Albuquerque (where Breaking Bad happen :D ) and Netherlands.

Broken-windows is not only applicable for police but also for other things in our life. Like your desk, your planning and your code. Pay attention to little mistake and fix it as soon as possible, or it soon will eat up your success :).

Running Drupal inside Symfony Framework

Yay! I managed to boot both Drupal 8 and Symfony Framework bundle in one Symfony setup. If you look at the screenshot closely, you will see Symfony Profile toolbar inside a Drupal setup.

The original idea is from Theodo, you use a bundle to bridge the between Drupal and Symfony, using EventListener to intercept the request and route to Drupal core if Symfony does not handle it.

So to run Drupal inside Symfony, first you need to start a new symfony application. Just follow the tutorial on the website.

Then you need to adjust the composer.json to include Drupal, and explicitly state the dependencies. At this time, you will have to use Symfony 2.4 or Composer will refuses to checkout due to dependencies conflict. Here is my composer.json. Make sure to run composer update  after that, it will takes a while to download all the dependencies.

Once all the dependencies are installed. Checkout or Download TheodoDrupal8Bundle to src. I have forked the origin repository and adjust some change to support core/install.php request. Since Drupal 8 also coming with it own vendor, you will need to modify vendor/drupal/drupal/core/vendor/composer/autoload_files.php and comment all items in the return part. Your autoload_files.php should look like below:

Then execute the following command in project root to expose Drupal’s resource to public folder.

And now when you run your symfony application, you should see the Drupal installation page :D

There are many interesting things to do, like bridging between Drupal entity and Symfony entity, synchronizing database configuration in 2 systems, integrating Symfony entities in views. But this is a good start already.

Android: quick way to remove spinner background

So, in an Android project, i have to remove the dropdown background of Android spinner and make it transparent completely. After a few googles, you can actually do this with custom style but I want a really quick way.

At first I try android:background="@android:color/transparent" inside Spinner tag, but it only make the spinner disappear (??). I also tried ShapeDrawable or LayerList but no luck. Spinner background parameter only accepts Graphic / Bitmap resource.

Then after a few tries, I found out the solution and it is quite simple. You just need to create a 1×1 transparent png, and set android:background="@drawable/transparent" . The background will disappear while the spinner still behaves correctly.

Simple trick but works :D


A Fresh Restart

Finally, I decide to archive my old blog and start a fresh one. If you are need something from my old blog, you can still find it here.

For this time, I will mainly focus on software engineering, my working projects, and – sometime – random thinking as well. Hopefully I can keep my pace on blogging to share and retain my thought.

You may notice that I switch from Drupal to WordPress for blogging. That’s because I want to focus on writing than updating drupal core and contributed modules, and after all WordPress blogging interface is far more attractive …

Oh by the way, Happy Vietnamese new year :)