it-swarm.com.de

Die maximale Anrufstapelgröße hat den Fehler überschritten

Ich verwende eine Direct Web Remoting (DWR) JavaScript-Bibliotheksdatei und erhalte eine Fehlermeldung nur in Safari (Desktop und iPad).

Es sagt 

Maximale Call-Stack-Größe überschritten.

Was genau bedeutet dieser Fehler und stoppt die Verarbeitung vollständig?

Auch ein Update für Safari browser (Eigentlich im iPad Safari, heißt es 

JS: Ausführung überschritten Zeitüberschreitung

ich gehe davon aus, dass es sich um das gleiche Call-Stack-Problem handelt.)

404
testndtv

Das bedeutet, dass Sie irgendwo in Ihrem Code eine Funktion aufrufen, die wiederum eine andere Funktion usw. aufruft, bis Sie das Call Stack-Limit erreicht haben.

Dies ist fast immer auf eine rekursive Funktion mit einem Basisfall zurückzuführen, der nicht erfüllt wird.

Stapel ansehen

Betrachten Sie diesen Code ...

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

Hier ist der Stapel nach einer Handvoll Anrufe ...

Web Inspector

Wie Sie sehen, wächst der Aufrufstapel, bis er ein Limit erreicht: die festgelegte Browser-Stack-Größe oder die Speicherbelegung.

Um dies zu beheben, stellen Sie sicher, dass Ihre rekursive Funktion einen Basisfall hat, der erfüllt werden kann.

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

Dies kann manchmal der Fall sein, wenn Sie dieselbe JS-Datei aus Versehen zweimal importieren/einbetten.

73
lucygenik

In meinem Fall habe ich Eingabeelemente anstelle ihrer Werte gesendet:

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

Anstatt:

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

Dadurch wurde mein Chrome-Tab auf einen Punkt eingefroren, der nicht einmal das "Warten/Töten" -Dialogfeld zeigte, als die Seite nicht mehr reagierte ...

34
FKasa

Es gibt irgendwo in Ihrem Code eine rekursive Schleife (d. H. Eine Funktion, die sich schließlich immer wieder aufruft, bis der Stack voll ist).

Andere Browser verfügen entweder über größere Stapel (so dass Sie stattdessen ein Timeout erhalten) oder sie schlucken den Fehler aus irgendeinem Grund (möglicherweise ein schlecht platzierter Try-Catch).

Verwenden Sie den Debugger, um die Aufrufliste zu überprüfen, wenn der Fehler auftritt.

25
Aaron Digulla

In meinem Fall habe ich ein großes Byte-Array mit folgendem Befehl in einen String konvertiert:

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

bytes enthielt mehrere Millionen Einträge, was zu groß ist, um auf den Stack zu passen.

11
Nate Glenn

Das Problem beim Erkennen von Stackoverflows ist, dass sich die Stack-Ablaufverfolgung manchmal abwickelt und Sie nicht sehen können, was tatsächlich vor sich geht.

Ich habe einige der neueren Debugging-Tools von Chrome für nützlich befunden.

Drücken Sie den Performance tab und vergewissern Sie sich, dass Javascript samples aktiviert ist.

Es ist ziemlich offensichtlich, wo der Überlauf hier ist! Wenn Sie auf extendObject klicken, sehen Sie tatsächlich die genaue Zeilennummer im Code. 

 enter image description here

Sie können auch Timings sehen, die hilfreich sein können oder nicht, oder einen roten Hering.

 enter image description here


Ein weiterer nützlicher Trick, wenn Sie das Problem nicht wirklich finden können, besteht darin, viele console.log-Anweisungen dort zu platzieren, wo Sie das Problem vermuten. Der vorstehende Schritt kann Ihnen dabei helfen.

Wenn Sie in Chrome wiederholt identische Daten ausgeben, werden diese so angezeigt, dass das Problem deutlicher ist. In diesem Fall traf der Stapel 7152 Frames, bevor er endgültig abstürzte:

 enter image description here

9
Simon_Weaver

Wenn Sie aus irgendeinem Grund einen unendlichen Prozess/eine unendliche Rekursion benötigen, können Sie einen Webworker in einem separaten Thread verwenden. http://www.html5rocks.com/de/tutorials/workers/basics/

wenn Sie dom-Elemente manipulieren und neu zeichnen möchten, verwenden Sie animation http://creativejs.com/resources/requestanimationframe/

5
Dr. Dama

Überprüfen Sie die Fehlerdetails in der Chrome-Dev-Symbolleisten-Konsole. Dadurch erhalten Sie die Funktionen in der Aufrufliste und führen Sie zu der Rekursion, die den Fehler verursacht.

5
chim

In meinem Fall wurde das Klickereignis für ein untergeordnetes Element propagiert. Also musste ich folgendes setzen:

e.stopPropagation ()

auf click event:

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

Hier ist der HTML-Code:

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

In meinem Fall wurden zwei jQuery-Modals übereinander angezeigt. Das zu verhindern, löste mein Problem. 

2
Barry Guvenkaya

Dies kann auch einen Maximum call stack size exceeded -Fehler verursachen:

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

Hier gilt das gleiche:

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

Aus dem Mozilla Docs :

Aber Vorsicht: Wenn Sie diese Methode verwenden, laufen Sie Gefahr, das Argumentlängenlimit der JavaScript-Engine zu überschreiten. Die Konsequenzen der Anwendung einer Funktion mit zu vielen Argumenten (denken Sie an mehr als Zehntausende von Argumenten) variieren je nach Modul (JavaScriptCore hat ein festes Argumentlimit von 65536), da das Limit (in der Tat sogar die Art eines übermäßig großen Stapels) Verhalten) ist nicht spezifiziert. Einige Motoren lösen eine Ausnahme aus. Noch schlimmer ist, dass andere die Anzahl der Argumente, die tatsächlich an die angewendete Funktion übergeben werden, willkürlich begrenzen. Um diesen letzteren Fall zu veranschaulichen: Wenn eine solche Maschine eine Grenze von vier Argumenten hätte (die tatsächlichen Grenzen sind natürlich wesentlich höher), wäre es so, als wären die Argumente 5, 6, 2, 3 für die obigen Beispiele übergeben worden. eher als das gesamte Array.

Also versuche:

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

Prüfen Sie, ob Sie eine Funktion haben, die sich selbst aufruft. Zum Beispiel 

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

In fast jeder Antwort heißt es, dass dies nur durch eine Endlosschleife verursacht werden kann. Das stimmt nicht, Sie könnten den Stack andernfalls durch tief verschachtelte Aufrufe überfahren (um nicht zu sagen, dass dies effizient ist, aber es ist durchaus möglich). Wenn Sie die Kontrolle über Ihre JavaScript-VM haben, können Sie die Stapelgröße anpassen. Zum Beispiel:

node --stack-size=2000

Siehe auch: Wie kann ich die maximale Aufrufstackgröße in Node.js erhöhen

0
ghayes

Ich bin auf dasselbe Problem gestoßen und habe nicht herausgefunden, was falsch ist, und habe angefangen, Babel die Schuld zu geben;)

Mit Code, der keine Ausnahme in Browsern zurückgibt:

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

problem wurde schlecht erstellt || (oder) part as babel erstellt eine eigene Typprüfung:

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

so entfernen

|| null

babel Transpilation gemacht hat funktioniert.

0
Raphael

Wenn Sie mit Google Maps arbeiten, prüfen Sie, ob die Länge von new google.maps.LatLng in einem geeigneten Format vorliegt. In meinem Fall wurden sie als undefiniert übergeben. 

0
User-8017771

Ich hatte diesen Fehler, weil ich zwei JS-Funktionen mit demselben Namen hatte

0
iceDragon

sie können Ihre rekursive Funktion im Chrome-Browser finden. Drücken Sie dazu Strg + Umschalttaste + j und dann auf die Registerkarte "Quelle". Auf diese Weise erhalten Sie Code-Kompilierungsfluss.

0
Vishal Patel

Ich war auch mit einem ähnlichen Problem konfrontiert, hier sind die Details beim Hochladen des Logos mit der Dropdown-Logo-Upload-Box

<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;
}

vor der Korrektur war mein 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]);
          }

Der Fehler in der Konsole: 

 enter image description here

Ich habe es gelöst, indem ich onclick="$('#filePhoto').click()" aus dem div-Tag entfernte.

0
spacedev

Wenn beide Aufrufe des identischen Codes unten um 1 verringert werden, funktionieren Chrome 32 auf meinem Computer, z. 17905 vs 17904. Wenn sie ausgeführt wird, wird der Fehler "RangeError: Maximale Aufrufstackgröße überschritten" ausgegeben. Es scheint, dass dieses Limit nicht fest codiert ist, sondern von der Hardware Ihres Computers abhängig ist. Es scheint jedoch, dass diese selbst auferlegte Grenze, wenn sie als eine Funktion aufgerufen wird, höher ist als wenn sie als Methode aufgerufen wird, d. H.

Als Methode aufgerufen:

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

ninja.chirp(17905);

Als Funktion aufgerufen:

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

chirp(20889);
0
Elijah Lynn

Das Problem in meinem Fall ist, dass ich Kinderrouten mit demselben Pfad wie das Elternteil habe:

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

Also musste ich die Linie der Kinderroute entfernen

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

Wir haben kürzlich ein Feld zu einer Admin-Site hinzugefügt, an der wir arbeiten - contact_type ... easy right? Nun, wenn Sie die Auswahl "Typ" aufrufen und versuchen, dies über einen jquery-Ajax-Aufruf zu senden, schlägt dieser Fehler fehl, der tief in jquery.js vergraben ist. Tun Sie dies nicht:

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

Das Problem ist dieser Typ: Typ - ich glaube, wir nennen das Argument "Typ" - eine Wertvariable mit dem Namen Typ zu haben, ist nicht das Problem. Wir haben dies geändert in:

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

Und some_function.php entsprechend umschreiben - Problem gelöst.

0
Scott

in meinem Fall erhalte ich diesen Fehler beim Aufruf von ajax, und die Daten, die ich versucht habe, diese Variable zu übergeben, wurden nicht definiert. Dies zeigt mir diesen Fehler an, beschreibt aber nicht die nicht definierte Variable. Ich fügte hinzu, dass die Variable n den Wert hat.

0
asifaftab87

Ich weiß, dass dieser Thread alt ist, aber ich denke, es ist erwähnenswert das Szenario, in dem ich dieses Problem gefunden habe, damit es anderen helfen kann.

Angenommen, Sie haben verschachtelte Elemente wie folgt:

<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>

Sie können die untergeordneten Elementereignisse innerhalb des Ereignisses des übergeordneten Elements nicht bearbeiten, da sie an sich selbst weitergegeben werden und rekursive Aufrufe ausführen, bis die Ausnahme ausgelöst wird.

Also wird dieser Code fehlschlagen:

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

    $('#profilePictureFile').trigger("click");
});

Sie haben zwei Möglichkeiten, dies zu vermeiden:

  • Bewegen Sie das Kind außerhalb des Elternteils.
  • Wenden Sie die Funktion stopPropagation auf das untergeordnete Element an.
0
Weslley Ramos

Ich war mit demselben Problem konfrontiert. Ich habe es gelöst, indem ich einen Feldnamen entfernt habe, der zweimal in Ajax verwendet wurde

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