summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/resources/js/jquery.ajaxdispatcher.js
blob: 68d48e749d7a7e9a4b1660310cede7a8f050d697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
( function () {
	'use strict';

	/**
	 * Call list of callbacks returning promises in serial order and returns a list of promises.
	 *
	 * @author Niklas Laxström
	 *
	 * @param {callable[]} list List of callbacks returning promises.
	 * @param {number} maxRetries Maximum number of times a failed promise is retried.
	 * @return {jQuery.Promise}
	 */
	function ajaxDispatcher( list, maxRetries ) {
		var deferred = $.Deferred();

		maxRetries = maxRetries || 0;

		return $.when( helper( list, maxRetries ) )
			.then( function ( promises ) {
				return deferred.resolve( promises );
			} ).fail( function ( errmsg ) {
				return deferred.reject( errmsg );
			} );
	}

	function helper( list, maxRetries ) {
		var first, rest, retries, retrier,
			deferred = $.Deferred();

		if ( list.length === 0 ) {
			deferred.resolve( [] );
			return deferred;
		}

		first = list.slice( 0, 1 )[ 0 ];
		rest = list.slice( 1 );

		retries = 0;
		retrier = function ( result, promise ) {
			if ( !promise.state ) {
				return;
			}

			if ( promise.state() === 'rejected' ) {
				if ( retries < maxRetries ) {
					retries += 1;
					return first.call().always( retrier );
				}
			}

			if ( promise.state() !== 'pending' ) {
				helper( rest, maxRetries ).always( function ( promises ) {
					deferred.resolve( [].concat( promise, promises ) );
				} );
			}
		};

		first.call().always( retrier ).catch( function ( errmsg ) {
			return deferred.reject( errmsg );
		} );

		return deferred;
	}

	$.extend( $, { ajaxDispatcher: ajaxDispatcher } );

}() );