/*global define*/ define([], function() { "use strict"; var Uri = Cesium.Uri; var when = Cesium.when; var defaultValue = Cesium.defaultValue; var activeRequests = {}; var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); function getServer(url) { var uri = new Uri(url).resolve(pageUri); uri.normalize(); var server = uri.authority; if (!/:/.test(server)) { server = server + ':' + (uri.scheme === 'https' ? '443' : '80'); } return server; } /** * Because browsers throttle the number of parallel requests allowed to each server, * this function tracks the number of active requests in progress to each server, and * returns undefined immediately if the request would exceed the maximum, allowing * the caller to retry later, instead of queueing indefinitely under the browser's control. * * @exports throttleRequestByServer * * @param {String} url The URL to request. * @param {throttleRequestByServer~RequestFunction} requestFunction The actual function that * makes the request. * @returns {Promise.|undefined} Either undefined, meaning the request would exceed the maximum number of * parallel requests, or a Promise for the requested data. * * * @example * // throttle requests for an image * var url = 'http://madeupserver.example.com/myImage.png'; * function requestFunction(url) { * // in this simple example, loadImage could be used directly as requestFunction. * return Cesium.loadImage(url); * }; * var promise = Cesium.throttleRequestByServer(url, requestFunction); * if (!Cesium.defined(promise)) { * // too many active requests in progress, try again later. * } else { * promise.then(function(image) { * // handle loaded image * }); * } * * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ function throttleRequestByServer(url, requestFunction) { var server = getServer(url); var activeRequestsForServer = defaultValue(activeRequests[server], 0); if (activeRequestsForServer >= throttleRequestByServer.maximumRequestsPerServer) { return undefined; } activeRequests[server] = activeRequestsForServer + 1; return when(requestFunction(url), function(result) { activeRequests[server]--; return result; }).otherwise(function(error) { activeRequests[server]--; return when.reject(error); }); } /** * Specifies the maximum number of requests that can be simultaneously open to a single server. If this value is higher than * the number of requests per server actually allowed by the web browser, Cesium's ability to prioritize requests will be adversely * affected. * @type {Number} * @default 6 */ throttleRequestByServer.maximumRequestsPerServer = 6; /** * A function that will make a request if there are available slots to the server. * @callback throttleRequestByServer~RequestFunction * * @param {String} url The url to request. * @returns {Promise.} A promise for the requested data. */ return throttleRequestByServer; });