Add async-foreach-behavior

Adds a utility behavior to enable looping over a list with promises.
This generalizes the asynchronous loop in the file-list's multi-diff
render process so that it can be used by other components.

Change-Id: I4c4cc729aed383ffb52b29b9f1f6c9ba0c83c77d
This commit is contained in:
Wyatt Allen
2017-09-30 10:52:31 +01:00
parent e7edad143c
commit b51b4656af
5 changed files with 93 additions and 17 deletions

View File

@@ -0,0 +1,37 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script>
(function(window) {
'use strict';
window.Gerrit = window.Gerrit || {};
/** @polymerBehavior Gerrit.AsyncForeachBehavior */
Gerrit.AsyncForeachBehavior = {
/**
* @template T
* @param {!Array<T>} array
* @param {!Function} fn
* @return {!Promise<undefined>}
*/
asyncForeach(array, fn) {
if (!array.length) { return Promise.resolve(); }
return fn(array[0]).then(() => this.asyncForeach(array.slice(1), fn));
},
};
})(window);
</script>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>async-foreach-behavior</title>
<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="async-foreach-behavior.html">
<script>
suite('async-foreach-behavior tests', () => {
test('loops over each item', () => {
const fn = sinon.stub().returns(Promise.resolve());
return Gerrit.AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
.then(() => {
assert.isTrue(fn.calledThrice);
assert.equal(fn.getCall(0).args[0], 1);
assert.equal(fn.getCall(1).args[0], 2);
assert.equal(fn.getCall(2).args[0], 3);
});
});
});
</script>

View File

@@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/async-foreach-behavior/async-foreach-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">

View File

@@ -118,6 +118,7 @@
},
behaviors: [
Gerrit.AsyncForeachBehavior,
Gerrit.KeyboardShortcutBehavior,
Gerrit.PatchSetBehavior,
Gerrit.PathListBehavior,
@@ -844,22 +845,20 @@
* @return {!Promise}
*/
_renderInOrder(paths, diffElements, initialCount) {
if (!paths.length) {
let iter = 0;
return this.asyncForeach(paths, path => {
iter++;
console.log('Expanding diff', iter, 'of', initialCount, ':', path);
const diffElem = this._findDiffByPath(path, diffElements);
diffElem.comments = this.$.commentAPI.getCommentsForPath(path,
this.patchRange, this.projectConfig);
const promises = [diffElem.reload()];
if (this._isLoggedIn) {
promises.push(this._reviewFile(path));
}
return Promise.all(promises);
}).then(() => {
console.log('Finished expanding', initialCount, 'diff(s)');
return Promise.resolve();
}
console.log('Expanding diff', 1 + initialCount - paths.length, 'of',
initialCount, ':', paths[0]);
const diffElem = this._findDiffByPath(paths[0], diffElements);
diffElem.comments = this.$.commentAPI.getCommentsForPath(paths[0],
this.patchRange, this.projectConfig);
const promises = [diffElem.reload()];
if (this._isLoggedIn) {
promises.push(this._reviewFile(paths[0]));
}
return Promise.all(promises).then(() => {
return this._renderInOrder(paths.slice(1), diffElements, initialCount);
});
},

View File

@@ -160,6 +160,7 @@ limitations under the License.
// Behaviors tests.
const behaviors = [
'async-foreach-behavior/async-foreach-behavior_test.html',
'base-url-behavior/base-url-behavior_test.html',
'docs-url-behavior/docs-url-behavior_test.html',
'keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html',