So, here's the workaround. The key is that the limit is "per execution", and an AJAX call (done through a standard Visualforce <apex:actionFunction>) is actually a single execution. I can "loop" in Javascript to do requests as long as I need it.
Let's have a look at the code.
The controller:
public with sharing class testJavascript {
public String requestStatus { get; set; }
public String requestMore { get; set; }
public Integer requestNumber { get; set; }
public Integer requestCurrent { get; set; }
public testJavascript () {
requestStatus = '';
requestMore = '';
requestNumber = 10000;
requestCurrent = 0;
}
public void doRequest () {
if (requestCurrent <= requestNumber) {
Http http = new Http();
for (Integer startPoint = requestCurrent; (requestCurrent <= requestNumber) && ((requestCurrent - startPoint) < 10); requestCurrent++) {
HttpRequest req = new HttpRequest();
req.setEndpoint('http://www.google.com');
req.setMethod('GET');
HTTPResponse res = http.send(req);
}
requestStatus = requestCurrent + ' out of ' + requestNumber + ' processed';
}
if (requestCurrent >= requestNumber)
requestMore = 'false';
else requestMore = 'true';
}
}
The page:
<apex:page controller="testJavascript">
<apex:form>
<apex:outputpanel id="status">
Status:
{!requestStatus}
<script>requestContinue = {!requestMore};</script>
</apex:outputpanel>
<script>
function requestMore() {
if (requestContinue)
doRequest();
}
</script>
<button onclick="if (doRequest()) return false; else return false;">Start</button>
<apex:actionfunction action="{!doRequest}" name="doRequest" oncomplete="requestMore()" rerender="status">
</apex:actionfunction></apex:form>
Some explication:
- In the controller I have a request counter (requestCurrent, set to 0 at beginning) and a request amount (requestNumber, set to 10000 at beginning) and a method, doRequest(), that, given those two variables, executes the next 10 HTTP requests (increasing the counter) and updates the status String (requestStatus) and the requestMore String/Boolean, setting it to true if other requests are needed (if the counter is lower than the request amount we need) or false if not.
- In the page I have an <apex:actionFunction> pointing to this method, that rerenders the status panel. In the panel I show the status string and I update a Javascript global variable (requestContinue) with the String/Boolean given in requestMore by the doRequest() APEX method.
- The actionFunction has an oncomplete attribute that calls another Javascript function, requestMore(), that is in the page code. This function checks for requestContinue value (updated after each rerender): if true calls again the doRequest() actionFunction and 10 more requests are executed, if false it does nothing.
The user has just to push the <button> (that does the first actionFunction call) to start the loop.
Nice, isn't it? :-)
This comment has been removed by the author.
ReplyDeleteThats great. There is also a solution which might help you.
ReplyDeleteYou can make more than 10 callouts by this approach:
http://techstuffdiary.wordpress.com/2014/02/28/no-callout-limit-and-doing-dmls-before-callout/
This solution is not working for me.I am still getting System.LimitException: Too many callouts: 11
ReplyDelete
ReplyDeleteThis information you provided in the blog that is really unique I love it!! Thanks for sharing such a great blog Keep posting..
Salesforce Training in Gurgaon
Salesforce Course in Gurgaon
Salesforce Institute in Gurgaon