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:
		| @@ -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> | ||||
| @@ -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> | ||||
| @@ -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"> | ||||
|   | ||||
| @@ -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); | ||||
|       }); | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Wyatt Allen
					Wyatt Allen