Convert AsyncForeachBehavior to util function

Change-Id: Ie4bf587c787b4864e0bdee1a7fafbfc3d760f81c
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 44700e9..df6490d 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -33,7 +33,7 @@
 import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
 import {PolymerElement} from '@polymer/polymer/polymer-element.js';
 import {htmlTemplate} from './gr-file-list_html.js';
-import {AsyncForeachBehavior} from '../../../behaviors/async-foreach-behavior/async-foreach-behavior.js';
+import {asyncForeach} from '../../../utils/async-util.js';
 import {DomUtilBehavior} from '../../../behaviors/dom-util-behavior/dom-util-behavior.js';
 import {PatchSetBehavior} from '../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.js';
 import {PathListBehavior} from '../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.js';
@@ -91,7 +91,6 @@
  * @extends PolymerElement
  */
 class GrFileList extends mixinBehaviors( [
-  AsyncForeachBehavior,
   DomUtilBehavior,
   KeyboardShortcutBehavior,
   PatchSetBehavior,
@@ -1292,7 +1291,7 @@
         detail: {resolve},
         composed: true, bubbles: true,
       }));
-    })).then(() => this.asyncForeach(files, (file, cancel) => {
+    })).then(() => asyncForeach(files, (file, cancel) => {
       const path = file.path;
       this._cancelForEachDiff = cancel;
 
diff --git a/polygerrit-ui/app/utils/async-util.js b/polygerrit-ui/app/utils/async-util.js
index 1d384bc..14d0288 100644
--- a/polygerrit-ui/app/utils/async-util.js
+++ b/polygerrit-ui/app/utils/async-util.js
@@ -15,34 +15,24 @@
  * limitations under the License.
  */
 
-/** @polymerBehavior AsyncForeachBehavior */
-export const AsyncForeachBehavior = {
-  /**
-   * @template T
-   * @param {!Array<T>} array
-   * @param {!Function} fn An iteratee function to be passed each element of
-   *     the array in order. Must return a promise, and the following
-   *     iteration will not begin until resolution of the promise returned by
-   *     the previous iteration.
-   *
-   *     An optional second argument to fn is a callback that will halt the
-   *     loop if called.
-   * @return {!Promise<undefined>}
-   */
-  asyncForeach(array, fn) {
-    if (!array.length) { return Promise.resolve(); }
-    let stop = false;
-    const stopCallback = () => { stop = true; };
-    return fn(array[0], stopCallback).then(exit => {
-      if (stop) { return Promise.resolve(); }
-      return this.asyncForeach(array.slice(1), fn);
-    });
-  },
-};
-
-// TODO(dmfilippov) Remove the following lines with assignments
-// Plugins can use the behavior because it was accessible with
-// the global Gerrit... variable. To avoid breaking changes in plugins
-// temporary assign global variables.
-window.Gerrit = window.Gerrit || {};
-window.Gerrit.AsyncForeachBehavior = AsyncForeachBehavior;
+/**
+ * @template T
+ * @param {!Array<T>} array
+ * @param {!Function} fn An iteratee function to be passed each element of
+ *     the array in order. Must return a promise, and the following
+ *     iteration will not begin until resolution of the promise returned by
+ *     the previous iteration.
+ *
+ *     An optional second argument to fn is a callback that will halt the
+ *     loop if called.
+ * @return {!Promise<undefined>}
+ */
+export function asyncForeach(array, fn) {
+  if (!array.length) { return Promise.resolve(); }
+  let stop = false;
+  const stopCallback = () => { stop = true; };
+  return fn(array[0], stopCallback).then(exit => {
+    if (stop) { return Promise.resolve(); }
+    return asyncForeach(array.slice(1), fn);
+  });
+}
diff --git a/polygerrit-ui/app/utils/async-util_test.js b/polygerrit-ui/app/utils/async-util_test.js
index 0a44884..df29e97 100644
--- a/polygerrit-ui/app/utils/async-util_test.js
+++ b/polygerrit-ui/app/utils/async-util_test.js
@@ -15,12 +15,13 @@
  * limitations under the License.
  */
 
-import '../../test/common-test-setup-karma.js';
-import {AsyncForeachBehavior} from './async-foreach-behavior.js';
-suite('async-foreach-behavior tests', () => {
+import '../test/common-test-setup-karma.js';
+import {asyncForeach} from './async-util.js';
+
+suite('async-util tests', () => {
   test('loops over each item', () => {
     const fn = sinon.stub().returns(Promise.resolve());
-    return AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
+    return asyncForeach([1, 2, 3], fn)
         .then(() => {
           assert.isTrue(fn.calledThrice);
           assert.equal(fn.getCall(0).args[0], 1);
@@ -36,7 +37,7 @@
       stop();
       return Promise.resolve();
     };
-    return AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
+    return asyncForeach([1, 2, 3], fn)
         .then(() => {
           assert.isTrue(stub.calledOnce);
           assert.equal(stub.lastCall.args[0], 1);