Maximale call-stackgrootte overschreden fout

Ik gebruik een Direct Web Remoting (DWR) JavaScript-bibliotheekbestand en krijg alleen een foutmelding in Safari (desktop en iPad)

Er staat

Maximale call-stack-grootte overschreden.

Wat betekent deze fout precies en stopt de verwerking volledig?

Ook een oplossing voor de Safari-browser (eigenlijk op de iPad Safari staat

JS:uitvoering overschreden time-out

waarvan ik aanneem dat het hetzelfde probleem is met de oproepstack)


Antwoord 1, autoriteit 100%

Het betekent dat je ergens in je code een functie aanroept die op zijn beurt een andere functie aanroept, enzovoort, totdat je de call-stacklimiet bereikt.

Dit komt bijna altijd door een recursieve functie met een basisgeval waaraan niet wordt voldaan.

De stapel bekijken

Overweeg deze code…

(function a() {
    a();
})();

Hier is de stapel na een handvol calls…

Web Inspector

Zoals je kunt zien, groeit de call-stack totdat deze een limiet bereikt: de hardcoded-stackgrootte van de browser of geheugenuitputting.

Om het op te lossen, moet u ervoor zorgen dat uw recursieve functie een basisgeval heeft waaraan kan worden voldaan…

(function a(x) {
    // The following condition 
    // is the base case.
    if ( ! x) {
        return;
    }
    a(--x);
})(10);

Antwoord 2, autoriteit 12%

U kunt dit soms krijgen als u per ongeluk hetzelfde JavaScript-bestand twee keer importeert/embedt, het is de moeite waard om uw bronnen-tabblad van de inspecteur te raadplegen.


Antwoord 3, autoriteit 11%

In mijn geval stuurde ik invoerelementen in plaats van hun waarden:

$.post( '',{ registerName: $('#registerName') } )

In plaats van:

$.post( '',{ registerName: $('#registerName').val() } )

Hierdoor werd mijn Chrome-tabblad zo vastgelopen dat ik niet eens het dialoogvenster ‘Wachten/Kill’ liet zien voor wanneer de pagina niet meer reageerde…


Antwoord 4, autoriteit 5%

Er is ergens een recursieve lus in je code (d.w.z. een functie die zichzelf uiteindelijk keer op keer aanroept totdat de stapel vol is).

Andere browsers hebben ofwel grotere stacks (u krijgt in plaats daarvan een time-out) of ze slikken de fout om de een of andere reden (misschien een slecht geplaatste try-catch).

Gebruik de debugger om de call-stack te controleren wanneer de fout optreedt.


Antwoord 5, autoriteit 3%

Het probleem met het detecteren van stackoverflows is dat de stacktrace soms niet meer werkt en je niet kunt zien wat er werkelijk aan de hand is.

Ik heb ontdekt dat enkele van de nieuwere foutopsporingstools van Chrome hiervoor nuttig zijn.

Klik op het Performance tab, zorg ervoor dat Javascript samples zijn ingeschakeld en je krijgt zoiets als dit.

Het is vrij duidelijk waar de overloop hier zit! Als u op extendObject klikt, kunt u het exacte regelnummer in de code zien.

voer hier de afbeeldingsbeschrijving in

Je kunt ook tijden zien die al dan niet nuttig kunnen zijn of een rode haring zijn.

voer hier de afbeeldingsbeschrijving in


Een andere handige truc als je het probleem niet echt kunt vinden, is om veel console.log-statements te plaatsen waar je denkt dat het probleem zit. De vorige stap hierboven kan je hierbij helpen.

Als u in Chrome herhaaldelijk identieke gegevens uitvoert, wordt dit als volgt weergegeven, zodat het duidelijker wordt waar het probleem zich voordoet. In dit geval bereikte de stapel 7152 frames voordat hij uiteindelijk crashte:

voer hier de afbeeldingsbeschrijving in


Antwoord 6, autoriteit 2%

In mijn geval was ik een array van grote bytes aan het omzetten in een string met behulp van het volgende:

String.fromCharCode.apply(null, new Uint16Array(bytes))

bytes bevatten enkele miljoenen items, wat te groot is om op de stapel te passen.


Antwoord 7

In mijn geval verspreidde de click-gebeurtenis zich op het onderliggende element. Dus ik moest het volgende plaatsen:

e.stopPropagation()

op klikgebeurtenis:

 $(document).on("click", ".remove-discount-button", function (e) {
           e.stopPropagation();
           //some code
        });
 $(document).on("click", ".current-code", function () {
     $('.remove-discount-button').trigger("click");
 });

Hier is de html-code:

 <div class="current-code">                                      
      <input type="submit" name="removediscountcouponcode" value="
title="Remove" class="remove-discount-button">
   </div>

Antwoord 8

Controleer de foutdetails in de Chrome-dev-werkbalkconsole, dit geeft je de functies in de call-stack en leidt je naar de recursie die de fout veroorzaakt.


Antwoord 9

Als je om de een of andere reden een oneindig proces/recursie nodig hebt, kun je een webworker in een aparte thread gebruiken.
http://www.html5rocks.com/en/tutorials/workers/basics/

als je dom-elementen wilt manipuleren en opnieuw wilt tekenen, gebruik dan animatie
http://creativejs.com/resources/requestanimationframe/


Antwoord 10

Dit kan ook de fout Maximum call stack size exceeded veroorzaken:

var items = [];
[].push.apply(items, new Array(1000000)); //Bad

Hetzelfde hier:

items.push(...new Array(1000000)); //Bad

Van de Mozilla Docs:

Maar let op: als u op deze manier van toepassing bent, loopt u het risico de
De limiet voor de argumentlengte van de JavaScript-engine. De gevolgen van
een functie toepassen met te veel argumenten (denk aan meer dan tientallen van
duizenden argumenten) verschillen per engine (JavaScriptCore heeft
hardgecodeerde argumentlimiet van 65536), omdat de limiet (inderdaad zelfs
de aard van elk gedrag met een te grote stapel) is niet gespecificeerd.
Sommige motoren zullen een uitzondering maken. Meer verderfelijk, anderen zullen
beperk willekeurig het aantal argumenten dat daadwerkelijk wordt doorgegeven aan de
toegepaste functie. Om dit laatste geval te illustreren: als zo’n motor
had een limiet van vier argumenten (werkelijke limieten zijn natuurlijk)
aanzienlijk hoger), zou het zijn alsof de argumenten 5, 6, 2, 3 hadden
doorgegeven om in de bovenstaande voorbeelden toe te passen, in plaats van de volledige
reeks.

Dus probeer:

var items = [];
var newItems = new Array(1000000);
for(var i = 0; i < newItems.length; i++){
  items.push(newItems[i]);
}

Antwoord 11

Bijna elk antwoord hier stelt dat dit alleen kan worden veroorzaakt door een oneindige lus. Dat is niet waar, je zou anders de stack kunnen overlopen door diep geneste calls (om niet te zeggen dat dat efficiënt is, maar het is zeker mogelijk). Als u controle heeft over uw JavaScript-VM, kunt u de stapelgrootte aanpassen. Bijvoorbeeld:

node --stack-size=2000

Zie ook: Hoe kan Ik verhoog de maximale call-stackgrootte in Node.js


Antwoord 12

In mijn geval werden twee jQuery-modaliteiten op elkaar gestapeld weergegeven. Dat voorkomen loste mijn probleem op.


Antwoord 13

We hebben onlangs een veld toegevoegd aan een beheerderssite waar we aan werken – contact_type… makkelijk toch? Nou, als je de select “type” aanroept en dat via een jQuery ajax-aanroep probeert te verzenden, mislukt het met deze fout diep begraven in jquery.js. Doe dit niet:

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, type:type }
});

Het probleem is dat type:type – ik geloof dat wij het zijn die het argument “type” noemen – het hebben van een waardevariabele met de naam type is niet het probleem. We hebben dit gewijzigd in:

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, contact_type:type }
});

En herschreef some_function.php dienovereenkomstig – probleem opgelost.


Antwoord 14

Beide aanroepen van de identieke code hieronder, indien verminderd met 1 werken in Chrome 32 op mijn computer, b.v. 17905 versus 17904. Als ze worden uitgevoerd zoals ze zijn, produceren ze de fout “RangeError: Maximum call-stackgrootte overschreden”. Het lijkt erop dat deze limiet niet hardcoded is, maar afhankelijk is van de hardware van uw machine. Het lijkt erop dat indien aangeroepen als een functie deze zelfopgelegde limiet hoger is dan wanneer aangeroepen als een methode, d.w.z. deze specifieke code gebruikt minder geheugen wanneer aangeroepen als een functie.

Aangeroepen als methode:

var ninja = {
    chirp: function(n) {
        return n > 1 ? ninja.chirp(n-1) + "-chirp" : "chirp";
    }
};
ninja.chirp(17905);

Aangeroepen als een functie:

function chirp(n) {
    return n > 1 ? chirp( n - 1 ) + "-chirp" : "chirp";
}
chirp(20889);

Antwoord 15

Ik had hetzelfde probleem
Ik heb het opgelost door een veldnaam te verwijderen die twee keer werd gebruikt op ajax
bijv.

    jQuery.ajax({
    url : '/search-result',
    data : {
      searchField : searchField,
      searchFieldValue : searchField,
      nid    :  nid,
      indexName : indexName,
      indexType : indexType
    },
.....

Antwoord 16

Het probleem in mijn geval is dat ik een kinderroute heb met hetzelfde pad met de bovenliggende :

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'prefix' },
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

Dus ik moest de lijn van de kinderroute verwijderen

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

Antwoord 17

Controleer of je een functie hebt die zichzelf aanroept. Bijvoorbeeld

export default class DateUtils {
  static now = (): Date => {
    return DateUtils.now()
  }
}

Antwoord 18

Voor mij als beginner in TypeScript was het een probleem in de getter en de setter van _var1.

class Point2{
    constructor(private _var1?: number, private y?: number){}
    set var1(num: number){
        this._var1 = num  // problem was here, it was this.var1 = num
    }
    get var1(){
        return this._var1 // this was return this.var1
    }
}

Antwoord 19

In mijn geval vergeet ik eigenlijk de value van input op te halen.

Fout

let name=document.getElementById('name');
param={"name":name}

Correct

let name=document.getElementById('name').value;
param={"name":name}

Antwoord 20

u kunt uw recursieve functie vinden in de crome-browser, druk op ctrl+shift+j en vervolgens op het tabblad Bron, waarmee u de code-compilatiestroom krijgt en u kunt zoeken naar het breekpunt in code.


Antwoord 21

Ik heb ook een soortgelijk probleem gehad, hier zijn de details
bij het uploaden van een logo met behulp van het dropdown-menu voor het uploaden van het logo

<div>
      <div class="uploader greyLogoBox" id="uploader" flex="64" onclick="$('#filePhoto').click()">
        <img id="imageBox" src="{{ $ctrl.companyLogoUrl }}" alt=""/>
        <input type="file" name="userprofile_picture"  id="filePhoto" ngf-select="$ctrl.createUploadLogoRequest()"/>
        <md-icon ng-if="!$ctrl.isLogoPresent" class="upload-icon" md-font-set="material-icons">cloud_upload</md-icon>
        <div ng-if="!$ctrl.isLogoPresent" class="text">Drag and drop a file here, or click to upload</div>
      </div>
      <script type="text/javascript">
          var imageLoader = document.getElementById('filePhoto');
          imageLoader.addEventListener('change', handleImage, false);
          function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {
                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }
      </script>
      </div>

CSS.css

.uploader {
  position:relative;
  overflow:hidden;
  height:100px;
  max-width: 75%;
  margin: auto;
  text-align: center;
  img{
    max-width: 464px;
    max-height: 100px;
    z-index:1;
    border:none;
  }
  .drag-drop-zone {
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.12);
    padding: 32px;
  }
}
.uploader img{
  max-width: 464px;
  max-height: 100px;
  z-index:1;
  border:none;
}
.greyLogoBox {
  width: 100%;
  background: #EBEBEB;
  border: 1px solid #D7D7D7;
  text-align: center;
  height: 100px;
  padding-top: 22px;
  box-sizing: border-box;
}
#filePhoto{
  position:absolute;
  width:464px;
  height:100px;
  left:0;
  top:0;
  z-index:2;
  opacity:0;
  cursor:pointer;
}

voor correctie was mijn code:

function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {
                  onclick="$('#filePhoto').click()"
                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }

De fout in console:

voer hier de afbeeldingsbeschrijving in

Ik heb het opgelost door onclick="$('#filePhoto').click()" uit de div-tag te verwijderen.


Antwoord 22

Ik weet dat deze thread oud is, maar ik denk dat het de moeite waard is om het scenario te noemen waarin ik dit probleem heb gevonden, zodat het anderen kan helpen.

Stel dat je geneste elementen hebt zoals deze:

<a href="#" id="profile-avatar-picker">
    <span class="fa fa-camera fa-2x"></span>
    <input id="avatar-file" name="avatar-file" type="file" style="display: none;" />
</a>

Je kunt de gebeurtenissen van het onderliggende element niet manipuleren binnen de gebeurtenis van de bovenliggende gebeurtenis, omdat deze zich naar zichzelf voortplant en recursieve oproepen doet totdat de uitzondering wordt gegenereerd.

Deze code zal dus mislukken:

$('#profile-avatar-picker').on('click', (e) => {
    e.preventDefault();
    $('#profilePictureFile').trigger("click");
});

Je hebt twee opties om dit te vermijden:

  • Verplaats het kind naar de buitenkant van de ouder.
  • Pas de functie stopPropagation toe op het onderliggende element .

Antwoord 23

Ik kreeg deze fout omdat ik twee JS Functions had met dezelfde naam


Antwoord 24

Als u met google maps werkt, controleer dan of de lat lng die worden doorgegeven aan new google.maps.LatLng de juiste indeling hebben. In mijn geval werden ze doorgegeven als ongedefinieerd.


Antwoord 25

in mijn geval krijg ik deze fout bij een ajax-aanroep en de gegevens die ik probeerde door te geven die variabele zijn niet gedefinieerd, dat toont me deze fout, maar beschrijft niet die variabele die niet is gedefinieerd. Ik heb gedefinieerd toegevoegd dat variabele n waarde heeft.


Antwoord 26

Ik kwam hetzelfde probleem tegen, kon er niet achter komen wat er aan de hand was en begon Babel de schuld te geven 😉

Met code die geen uitzondering retourneert in browsers:

if (typeof document.body.onpointerdown !== ('undefined' || null)) {

probleem is slecht gemaakt || (of) part as babel creëert zijn eigen typecontrole:

function _typeof(obj){if(typeof Symbol==="function"&&_typeof(Symbol.iterator)==="symbol")

dus verwijderen

|| null

heeft ervoor gezorgd dat babytranspilatie werkte.


Antwoord 27

In mijn geval
Ik heb per ongeluk dezelfde variabelenaam toegewezen en aan val-functie “class_routine_id”

var class_routine_id = $("#class_routine_id").val(class_routine_id);

het zou moeten zijn:

 var class_routine_id = $("#class_routine_id").val(); 

Antwoord 28

in Angular, als je mat-select gebruikt en 400+ opties hebt, kan deze fout optreden
https://github.com/angular/components/issues/12504

je moet de @angular/material version updaten


Antwoord 29

Ik gebruik React-Native 0.61.5 samen met (npm 6.9.0 & node 10.16.1)

Terwijl ik nieuwe bibliotheken in Project installeer, kreeg ik een van

(bijv. npm install @react-navigation/native –save)

Fout bij maximale aanroepstapel overschreden

daarvoor probeer ik

sudo npm cache clean –force

(Opmerking:- Onderstaande opdracht duurt meestal duur 1 tot 2 minuten
afhankelijk van uw npm cache grootte)


Antwoord 30

Ik kreeg deze fout in de express/nodejs-app, wanneer het schema van de MongoDB-database en de modellen die we hebben gemaakt niet overeenkomen.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

twenty − 4 =

Other episodes