title: Recursive function ending early in iOS
body: <h2>Problem</h2>
  
  <p>I have a recursive function which loops through about 20,000 items in an array.
   It works fine on desktop, but stops after about 10,600 iterations in iOS Safari and Chrome.</p>
  
  <h2>Attempts</h2>
  
  <p><em>Note: I'm doing this in a web worker to avoid blocking the UI, but the issue can be reproduced without one, so I removed it for testing. I also removed the array and I'm just incrementing <code>i</code> in the following code.</em></p>
  
  <p><strong>First attempt</strong> <em>(does not finish on iOS)</em><strong>:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>window.onload = function(){
      var i = 0, max = 20000, status = document.body;
      foo();
  
      function foo(){
   status.innerHTML = i + '/' + max; // Just for testing - not in my code
   if(i &lt; max){
       i++;
       foo();  // Calling the function immediately
          }
      }
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>Second attempt</strong> <em>(works, but is really slow)</em><strong>:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>window.onload = function(){
      var i = 0, max = 20000, status = document.body;
      foo();
  
      function foo(){
   status.innerHTML = i + '/' + max; // Just for testing - not in my code
   if(i &lt; max){
       i++;
       setTimeout(foo,0);  // Using a timeout
          }
      }
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>Third attempt</strong> <em>(works great, but looks hacky)</em><strong>:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>window.onload = function(){
      var i = 0, max = 20000, status = document.body;
      foo();
  
      function foo(){
   status.innerHTML = i + '/' + max; // Just for testing - not in my code
   if(i &lt; max){
       i++;
       if(i%1000 == 0) setTimeout(foo,0);  // Using timeout every 1000 items
       else foo();                         // Calling immediately otherwise
          }
      }
  };</code></pre>
  </div>
  </div>
  </p>
  
  <h2>Questions</h2>
  
  <ol>
  <li><p>Why is the first attempt not working? Is it because of memory?</p></li>
  <li><p>Although the third attempt works fine, it seems to be hacky, so I'm wondering if there is a cleaner way to do it?</p></li>
  </ol>