Example of async/await

Use of BlueImp LoadImage library to demonstrate the power of ES7 async/await with Babel.

by EastJesus

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.29/browser-polyfill.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.6.1/load-image.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/javascript-canvas-to-blob/3.3.0/js/canvas-to-blob.min.js"></script>
<p>Try to load one or multiple images.</p>

<p>The main advantage of loadImage is that you can get EXIF datas from a picture to know its original orientation (and then rotate it accordingly). <a href="http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/">Know more here</a>. So you can find "oriented" <a href="https://github.com/recurser/exif-orientation-examples">pictures samples here</a>.</p>

<p>Take a look at the comments in the JS code, and at your console, too.</p>

<p><input type="file" multiple></p>

CSS

img {
  width: 200px;
  max-width: 100%;
}

Babel + JSX

console.clear()

$(':file').on('change', (e) => {

  // Main thread, not blocked by the async each function below	
  console.clear()
	console.log('images dropped')
  $('img').remove()

  // Async thread for each file
  $.each(e.target.files, async function(i) {
  	console.log(`image #${i} processing begins`)

    const file = this

    // 1. First function: no callback, just a variable assign!
    
    let metas = await PicturesService.getMetas({
      file
    })

    console.log(metas)

    // 2. This function will wait for the above to be executed
    
    let resized = await PicturesService.resize({
      file,
      opts: {
        orientation: metas.orientation,
        maxWidth: 1000,
        maxHeight: 1000
      }
    })

    console.log(resized)

    // 3. You can do anything synchrone-like between awaits
    // Here we add the dimensions of the new picture to its meta infos
    
    metas = Object.assign({
      width: resized.width,
      height: resized.height
    }, metas)

    console.log(metas)

    // 4. Same here
    
    let converted = await PicturesService.convert({
      canvas: resized,
      opts: {
        compression: 0.8,
        format: 'image/jpeg'
      }
    })

    // 5. Same here
    
    const preview = await PicturesService.toBase64(converted)
    
    console.log(`image #${i} processing ends`)

    // 6. Update DOM when all async function have finished
    
    $('body').append( $(`<img src="${preview}">`) );
  })

  console.log('Main thread is not blocked!')
})




// --------------
// PicturesService
// Take attention to `async` keywords and use of `Promises`
// --------------




let PicturesService = {};

// Arguments: File file
// Returns: object of metas informations
PicturesService.getMetas = async function({file}) {

  return new Promise((resolve, reject) => {
    loadImage.parseMetaData(file, (data) => {
      const exif = data.exif ? data.exif.getAll() : [];
      let orientation, location, dateTime;

      if(...