Using es6 promises server side in Apps Script

In Using promises with apps script I showed how to use promises with HTML service as a better way of managing asynchronous functions (especially google.script.run) from the client. 

Promises are a great way to express the order that things have to happen in, and to manage return values from multiple processes. Although Apps Script is synchronous (today anyway), using the same paradigm regardless of whether you are running code on the server or the client makes things more consistent and easy to express.

Apps Script doesn't support promises at all, but you can use a polyfill to make it so that it does - giving you all the syntactic benefits of promises (even though we can't really use the orchestration asynchronicity yet).

Here's how.

Polyfill library

As usual, I have a library that looks after the polyfill for you. Here's the key.

MfZp_89LhuhiFvEH_ry05PCz3TLx7pV4j


The code is on Github if you want to make your own. 

Using the Polyfill library

Any functions you write will return a promise, instead of an actual result. Any code that wants to consume the result does so like this.
yourFunction (args).then (
   function (result) {
     // do something with the result
   },
   function (err) {
     // do something with the error
   }
);

That may seem a little more complicated than 
   var result = yourFunction(args);

but one immediate benefit you can see is that error and success handling are built in. 

Another benefit is that  you can do this
var p1 = yourFunctionA();
var p2 = yourFunctionB();
var p3 = yourFunctionC();

Promise.all ([p1,p2,p3]).then ( 
  function (results) {
     // all the results
  },
  function (errors) {
     // if anything has failed
  }
);

But the biggest benefit is that you can write code that is going to be easily transferable between the server and the client (where you can take advantage of asynchronicity. 

Returning promises


Functions need to return a promise rather than a result. Here's and example of one.

function yourFunction  (url, options) {
    return new cPromisePolyfill.Promise (function ( resolve, reject ) {
      try {
        options = options || {};
        var result = UrlFetchApp.fetch (url , options);
        resolve (result.getContentText());
      }
      
      catch (err) {
        Logger.log(err);
        reject (err);
      }
      
    });
}

In summary, if the function fails then
 reject(errordata)

if it succeeds
 resolve (result)

The code

Here's the key for the library, and it's also on github, or below. There's also some test code on GitHub

MfZp_89LhuhiFvEH_ry05PCz3TLx7pV4j


// this loads the es6-promises polyfill to make promise syntax available in Apps Script
// copyright notice - https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
var Promise,
    setTimeout = setTimeout || function (func,ms) {
      Utilities.sleep(ms);
      func();
    };

(function () {  

  // get the polyfill and eval
  if (!Promise) {
    var result = UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/es6-promise/3.2.1/es6-promise.min.js');
    eval (result.getContentText());

    // add done for compatibility with other promise systems
    Promise.prototype.done = Promise.prototype.done || Promise.prototype.then ;

  }
  
}());


For more like this, see Google Apps Scripts snippets. Why not join our forumfollow the blog or follow me on twitter to ensure you get updates when they are available. 

You want to learn Google Apps Script?

Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, available All formats are available now from O'Reilly,Amazon and all good bookshops. You can also read a preview on O'Reilly

If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.






Comments