function mapThenable(chunk, thenable, context, bodies, callback) {
    return chunk.map(function(asyncChunk) {
      thenable.then(function(data) {
        try {
          callback(asyncChunk, data);
        } catch (err) {
          // handle errors the same way Chunk#map would.  This logic is only here since the thenable defers
          // logic such that the try / catch in Chunk#map would not capture it.
          dust.log(err, ERROR);
          asyncChunk.setError(err);
        }
      }, function(err) {
        dust.log('Unhandled promise rejection in `' + context.getTemplateName() + '`', INFO);
        asyncChunk.renderError(err, context, bodies).end();
      });
    });
  }
Like Chunk#map but additionally resolves a thenable.  If the thenable succeeds the callback is invoked with
a new chunk that can be used to asynchronously render or write to it, otherwise if the thenable is rejected
then the error body is rendered if available, an error is logged, and the callback is never invoked.
@param {Chunk} The current chunk to insert a new chunk
@param thenable {Thenable} the target thenable to await
@param context {Context} context to use to render the deferred chunk
@param bodies {Object} may optionally contain an "error" for when the thenable is rejected
@param callback {Function} The function that will be called with the new chunk
@returns {Chunk} A copy of this chunk instance in order to further chain function calls on the chunk