function asyncForEach(items, loopBody) {
  return new Promise(function(resolve) {
    let index = 0;

    function loop() {
      const item = items[index++];
      if (item)
        loopBody(item).then(loop);
      else
        resolve();
    }

    loop();
  });
}
/**
 * Will call |loopBody| for each item in |items|. Will only move to the next
 * item after the promise from |loopBody| resolves.
 * @param {!Array<Object>} items
 * @param {!function(!Object):!Promise} loopBody
 * @return {!Promise}
 */
Will call |loopBody| for each item in |items|. Will only move to the next
item after the promise from |loopBody| resolves.
Will call |loopBody| for each item in |items| . Will only move to the next item after the promise from |loopBody| resolves .
function asyncForEach(items, loopBody) {
  return new Promise(function(resolve) {
    let index = 0;
    function loop() {
      const item = items[index++];
      if (item)
        loopBody(item).then(loop);
      else
        resolve();
    }
    loop();
  });
}
function asyncForEach ( items , loopBody ) { return new Promise ( function ( resolve ) { let index = 0 ; function loop ( ) { const item = items [ index ++ ] ; if ( item ) loopBody ( item ) . then ( loop ) ; else resolve ( ) ; } loop ( ) ; } ) ; }
Will call |loopBody| for each item in |items|.
Will call |loopBody| for each item in |items| .