Dart's Async / Await is here. The Future starts now




The latest development release of the Dart Editor includes experimental support for Async / Await.  Check out Gilad's article for an introduction. In the Editor go into preferences -> experimental to enable this feature.

async / await is "syntactic sugar" for what can be accomplished using Futures, Completors and a whack of nested then() closures. But this sugar is ohh so sweet (and calorie free!).  Your code will be much easier to understand and debug.


Here is a little before and after example using async/await. In this example, we need to perform 3 async LDAP operations in sequence. Using Futures and nested then() closures, we get something like this:



    // add mickey to directory  
    ldap.add(dn, attrs).then( expectAsync((r) {  
     expect( r.resultCode, equals(0));  
     // modify mickey's sn  
     var m = new Modification.replace("sn", ["Sir Mickey"]);  
     ldap.modify(dn, [m]).then( expectAsync((result) {  
      expect(result.resultCode,equals(0));  
      // finally delete mickey  
      ldap.delete(dn).then( expectAsync((result) {  
       expect(result.resultCode,equals(0));  
      }));  
     }));  
    }));  


Kinda ugly isn't it?  And hard to type (did you miss a closing brace somewhere??).  The sequence of operations is just not easy to see. If we add in error handling for each Future operation, this gets even worse.


So let's rewrite using async/await:



     // add mickey
      var result = await ldap.add(dn, attrs);
      expect( result.resultCode, equals(0));
      // modify mickey's sn
      var m = new Modification.replace("sn", ["Sir Mickey"]);
      result = await ldap.modify(dn, [m]);
      expect(result.resultCode,equals(0));
      // finally delete mickey
      result = await ldap.delete(dn);
      expect(result.resultCode,equals(0));


The intent of the async/await version is much easier to follow, and we can eliminate the unit test expectAsync weirdness.

If any of the Futures throws an exception, we can handle that with a nice vanilla try / catch block.  Here is a sample unit test where the Future is expected to throw an error:



    test('Bind to a bad DN', () async {
      try {
        await ldap.bind("cn=foofoo","password");
        fail("Should not be able to bind to a bad DN");
      }
      catch(e) {
       expect(e.resultCode,equals(ResultCode.INVALID_CREDENTIALS));
      }
    });

Note the use of the "async" keyword before the curly brace. You must mark a function as async in order to use await.

Yet another reason to love Dart!





Comments

Popular posts from this blog

Introducing ds-operator, the ForgeRock Directory Services Operator for Kubernetes

OAM R2 REST APIs for Policy Management

Automating OpenDJ backups on Kubernetes