zurück zur Startseite
  


Zurück XHTMLforum > Webentwicklung (außer XHTML und CSS) > Javascript & Ajax
Seite neu laden JS wartet nich auf Ende von rekursiver Funktion

Antwort
 
LinkBack Themen-Optionen Ansicht
  #1 (permalink)  
Alt 21.07.2011, 22:21
Michael Walter
XHTMLforum-Mitglied
Thread-Ersteller
 
Registriert seit: 16.02.2010
Ort: Berlin
Beiträge: 237
Walter IT-Services befindet sich auf einem aufstrebenden Ast
Standard JS wartet nich auf Ende von rekursiver Funktion

Hallo zusammen!

Ich habe in Problem mit rekursiven Funktionsaufrufen in JS.
Und zwar, wartet JS nicht auf das Ende des letzten Funktionsaufrufs aus der Funktion selbst heraus, sondern macht direkt nach dem ersten Aufruf der Hauptfunktion einfach weiter. Wie kann ich das verhindern?

Ich könnte mir auch vorstellen, dass es daran liegt, dass ich die Rekursion mit window.setTimeout() auslöse. Wenn ja, wie kann ich das umgehen?

Hier mal ein Beispiel:
HTML-Code:
<?php
header('content-type: text/html; charset=utf-8');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <title>Background Click</title>
    <link rel="stylesheet" type="text/css" href="reset.css" />
    <script type="text/javascript">
    var config = new Array();
    config['debug'] = 'false';
    config['text_speed'] = 30;

function show_text(text,pos)
{
	if(config['debug'] != 'true' && text == 'kein JSON')
	{
		document.getElementById('box_text').innerHTML = 'Ein Fehler ist aufgetreten';
		return false;
	}
	
	if(config['text_speed'] == 'instant') document.getElementById('box_text').innerHTML = text;
	else
	{
		a_pos = text.indexOf('<a ',pos);
		if(typeof pos == 'undefined') pos = 0;
		pos = parseInt(pos);
//		if(pos == 0) block_box(text);
		document.getElementById('box_text').innerHTML = text.substr(0,pos);
		new_letter = document.createElement('span');
		bla = text.indexOf('<br />');
		blubb = text.indexOf('<br />',pos);
		if(text.indexOf('<br />',pos) == pos)
		{
			new_letter.innerHTML = '<br />';
			pos += 5;
		}
		else if(text.indexOf('<a ',pos) == pos)
		{
			tmp = text.substring(pos);
			end = tmp.search(/>/);
			pos += end;
		}
		else if(text.indexOf('</a>',pos) == pos)
		{
			new_letter.innerHTML = '<br />';
			pos += 3;			
		}
		else new_letter.innerHTML = text.charAt(pos);
		
		document.getElementById('box_text').appendChild(new_letter);
		max_pos = text.length - 1;
		pos++;
		call = 'show_text("' + text + '",' + pos + ');';
		if(pos <= max_pos) setTimeout(call,parseInt(config['text_speed']));
		//else ende
	}
	return false;
}
    </script>
  </head>
  <body>
    <div id="box_text">
     bla
    </div>
    <br /><br />
    <input type="button" name="none" value="klick mich" onclick="show_text('Hallo! Ich bin ein lustiger Text!');alert('blubb');"/>
  </body>
</html>
Wäre nett, wenn mir da einer weiterhelfen kann.
Vielen dank im Voraus

LG
Micha
__________________
Walter IT-Services
Michael Walter

http://www.walter-it.de
http://blog.walter-it.de
Mit Zitat antworten
Sponsored Links
  #2 (permalink)  
Alt 21.07.2011, 22:40
Benutzerbild von mantiz
Erfahrener Benutzer
XHTMLforum-Kenner
 
Registriert seit: 25.02.2007
Beiträge: 2.843
mantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz sein
Standard

Ja, ist klar, Du startest mit "setTimeout" einen Timer, welcher die übergebene Funktion nach der angegebenen Zeit aufruft, aber nach dem Starten des Timers wird sofort zur aufrufenden Funktion zurückgekehrt.

Afaik gibt es in Javascript keine sleep-Funktion. Habe gerade nochmal danach gesucht, aber auch nichts wirkliches gefunden.

Das beste wäre es wohl, wenn Du die Funktion so umbaust/splittest, dass der Code, der nach "setTimeout" ausgeführt werden soll, innerhalb der Funktion, die an "setTimeout" übergeben wird, getriggert wird.

Hmpf, etwas kompliziert geschrieben, aber ich hoffe Du verstehst was ich meine.

Bei meiner Suche habe ich z.B. Lösungen gesehen, die die ursprüngliche Funktion mit einem Status-Parameter aufrufen, so nach dem Motto:

Code:
function foo(state) {
   if (!state || state == 1) {
      // code vor setTimeout
      setTimeout(...); // hier dann die Fkt. "foo" aufrufen, wobei state=2 übergeben wird
   }
   if (state == 2) {
      // code der nach setTimeout ausgeführt werden soll
   }
   state++;
}
Hab' das Suchergebnis jetzt nicht mehr zur Hand, aber das Konzept sollte klar sein.
Mit Zitat antworten
Sponsored Links
  #3 (permalink)  
Alt 22.07.2011, 00:11
Michael Walter
XHTMLforum-Mitglied
Thread-Ersteller
 
Registriert seit: 16.02.2010
Ort: Berlin
Beiträge: 237
Walter IT-Services befindet sich auf einem aufstrebenden Ast
Standard

Vielen Dank für den Tip.

Leider sehe ich nicht, wie diesen auf mein Problem anwenden kann.
Im Prinzip gibt es innerhalb der Funktion selbst keinen Code nach dem TimeOut.
Der Code oben ist nur ein Test-Case. Letzendlich wird die show_text()-Funktion aufgerufen und danach geht eine Menge anderer Code weiter (Aufruf ist innerhalb der Methode einer Klasse).

Verschiedene "sleep()"-Nachbauten haben es leider auch nicht gebracht, da dort der Effekt leider nicht mehr zur Geltung kommt, da der Brwoser-Tab hängt, bis die letzte Rekursion abgeschlossen ist.

Bin gerne noch für Anregungen und weiter Tips offen.


LG
Micha
__________________
Walter IT-Services
Michael Walter

http://www.walter-it.de
http://blog.walter-it.de
Mit Zitat antworten
  #4 (permalink)  
Alt 22.07.2011, 10:19
Benutzerbild von inta
free as in freedom
XHTMLforum-Kenner
 
Registriert seit: 04.12.2006
Ort: Berlin
Beiträge: 5.016
inta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz seininta kann auf vieles stolz sein
Standard

Du könntest in deiner Funktion ein Event feuern, wenn diese komplett fertig ist. Für die Javascript-Funktionen die davon abhängig sind und nicht vorher ausgeführt werden sollen, registrierst du dann einen ensprechenden Event-Listener.
Mit Zitat antworten
  #5 (permalink)  
Alt 22.07.2011, 14:20
Benutzerbild von protonenbeschleuniger
Verbesserer
XHTMLforum-Kenner
 
Registriert seit: 06.09.2007
Beiträge: 4.977
protonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblick
Standard

Genau! Du musst dein Skript Eventgesteuert ablaufen lassen und mit closures und Funktionsreferenzen arbeiten. So kommst du nicht weiter.

Dein call müßte z.b. so aussehen:
Code:
var call = function() { show_text(text, pos);};
if(pos <= max_pos) setTimeout(call,parseInt(config['text_speed']));
Das ist übrigens auch keine rekursive Funktion. Der Aufruf im setTimeout ist nicht mehr im gleichen Scope, auch wenn du die gleiche Funktion aufrufst.
Mit Zitat antworten
  #6 (permalink)  
Alt 22.07.2011, 18:53
Michael Walter
XHTMLforum-Mitglied
Thread-Ersteller
 
Registriert seit: 16.02.2010
Ort: Berlin
Beiträge: 237
Walter IT-Services befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von inta Beitrag anzeigen
Du könntest in deiner Funktion ein Event feuern, wenn diese komplett fertig ist. Für die Javascript-Funktionen die davon abhängig sind und nicht vorher ausgeführt werden sollen, registrierst du dann einen ensprechenden Event-Listener.
Vielen Dank für den Tipp!
Da muss ich mich mal mit den Event-Handlern beschäftigen.

Ich denke mal, dass es bei scriptaculous ähnlich gemacht wird. Denn dort hat man auch immer den afterFinish-Callback. Der muss ja auch durch irgendwas ausgelöst werden.

Zitat:
Zitat von protonenbeschleuniger Beitrag anzeigen
Genau! Du musst dein Skript Eventgesteuert ablaufen lassen und mit closures und Funktionsreferenzen arbeiten. So kommst du nicht weiter.

Dein call müßte z.b. so aussehen:
Code:
var call = function() { show_text(text, pos);};
if(pos <= max_pos) setTimeout(call,parseInt(config['text_speed']));
Das ist übrigens auch keine rekursive Funktion. Der Aufruf im setTimeout ist nicht mehr im gleichen Scope, auch wenn du die gleiche Funktion aufrufst.
Danke. Sowas ähnliches dachte ich mir schon.
Deinen Vorschlag habe ich irgenwo auch schon einmal gelesen.
Das Problem wurde damit aber leider nicht gelöst :/

LG
Micha
__________________
Walter IT-Services
Michael Walter

http://www.walter-it.de
http://blog.walter-it.de
Mit Zitat antworten
  #7 (permalink)  
Alt 22.07.2011, 19:06
Erfahrener Benutzer
XHTMLforum-Mitglied
 
Registriert seit: 13.07.2006
Beiträge: 745
mermshaus ist ein wunderbarer Anblickmermshaus ist ein wunderbarer Anblickmermshaus ist ein wunderbarer Anblickmermshaus ist ein wunderbarer Anblickmermshaus ist ein wunderbarer Anblickmermshaus ist ein wunderbarer Anblick
Standard

Dein Beispiel aus dem ersten Post mit Callback-Möglichkeit und Closure.

Code:
<?php
header('content-type: text/html; charset=utf-8');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <title>Background Click</title>
    <link rel="stylesheet" type="text/css" href="reset.css" />
    <script type="text/javascript">
    var config = new Array();
    config['debug'] = 'false';
    config['text_speed'] = 30;

function show_text(text, callback, pos)
{
    if(config['debug'] != 'true' && text == 'kein JSON')
    {
        document.getElementById('box_text').innerHTML = 'Ein Fehler ist aufgetreten';
        return false;
    }

    if(config['text_speed'] == 'instant') document.getElementById('box_text').innerHTML = text;
    else
    {
        a_pos = text.indexOf('<a ',pos);
        if(typeof pos == 'undefined') pos = 0;
        pos = parseInt(pos);
//        if(pos == 0) block_box(text);
        document.getElementById('box_text').innerHTML = text.substr(0,pos);
        new_letter = document.createElement('span');
        bla = text.indexOf('<br />');
        blubb = text.indexOf('<br />',pos);
        if(text.indexOf('<br />',pos) == pos)
        {
            new_letter.innerHTML = '<br />';
            pos += 5;
        }
        else if(text.indexOf('<a ',pos) == pos)
        {
            tmp = text.substring(pos);
            end = tmp.search(/>/);
            pos += end;
        }
        else if(text.indexOf('</a>',pos) == pos)
        {
            new_letter.innerHTML = '<br />';
            pos += 3;
        }
        else new_letter.innerHTML = text.charAt(pos);

        document.getElementById('box_text').appendChild(new_letter);
        max_pos = text.length - 1;
        pos++;

        call = (function (text, callback, pos) {
            return function () {
                show_text(text, callback, pos);
            };
        })(text, callback, pos);

        if(pos <= max_pos) setTimeout(call,parseInt(config['text_speed']));
        else {
            callback();
        }
    }
    return false;
}
    </script>
  </head>
  <body>
    <div id="box_text">
     bla
    </div>
    <br /><br />
    <input type="button" name="none" value="klick mich"
           onclick="show_text('Hallo! Ich bin ein lustiger Text!',
                              function () { alert('blubb'); });"/>
  </body>
</html>

Geändert von mermshaus (22.07.2011 um 19:08 Uhr)
Mit Zitat antworten
  #8 (permalink)  
Alt 22.07.2011, 19:16
Benutzerbild von protonenbeschleuniger
Verbesserer
XHTMLforum-Kenner
 
Registriert seit: 06.09.2007
Beiträge: 4.977
protonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblickprotonenbeschleuniger ist ein wunderbarer Anblick
Standard

Code:
function show_text(text, onend){
	if(config['debug'] != 'true' && text == 'kein JSON')
	{
		document.getElementById('box_text').innerHTML = 'Ein Fehler ist aufgetreten';
		return false;
	}
	
	if(config['text_speed'] == 'instant') document.getElementById('box_text').innerHTML = text;
	else {
        if(typeof pos == 'undefined') pos = 0;
        
        function lauftext() {
             a_pos = text.indexOf('<a ',pos);
            
            pos = parseInt(pos);
    //		if(pos == 0) block_box(text);
            document.getElementById('box_text').innerHTML = text.substr(0,pos);
            new_letter = document.createElement('span');
            bla = text.indexOf('<br />');
            blubb = text.indexOf('<br />',pos);
            if(text.indexOf('<br />',pos) == pos)
            {
                new_letter.innerHTML = '<br />';
                pos += 5;
            }
            else if(text.indexOf('<a ',pos) == pos)
            {
                tmp = text.substring(pos);
                end = tmp.search(/>/);
                pos += end;
            }
            else if(text.indexOf('</a>',pos) == pos)
            {
                new_letter.innerHTML = '<br />';
                pos += 3;			
            }
            else new_letter.innerHTML = text.charAt(pos);
            
            document.getElementById('box_text').appendChild(new_letter);
            max_pos = text.length - 1;
            pos++;
            if(pos <= max_pos) window.setTimeout(lauftext,parseInt(config['text_speed']));
            else onend();
        }
        window.setTimeout(lauftext,parseInt(config['text_speed']));
	}
	return false;
}
Der Aufruf:
HTML-Code:
<input 
    type="button" 
    name="none" 
    value="klick mich" 
    onclick="show_text('Hallo! Ich bin ein lustiger Text!', function() {alert('blubb');})">
Nachtrag: ooops, ich hatte den Post von Mermshaus nicht gesehen.

Geändert von protonenbeschleuniger (22.07.2011 um 19:28 Uhr)
Mit Zitat antworten
Antwort

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
wieso wartet die funktion nicht css anfaenger CSS 1 17.08.2010 14:29
[PROTOTYPE] Funktion erst beenden, wenn Ajax Aufruf abgeschlossen ist naitsab Javascript & Ajax 3 09.04.2009 16:41
Code einer bestehenden Funktion hinzufügen cybertron Javascript & Ajax 13 01.01.2009 16:53
Funktion gibt Array nicht zurück Schneemann Serveradministration und serverseitige Scripte 8 05.05.2008 02:14
[PHP] Funktion zum Optimieren von CSS Floele Serveradministration und serverseitige Scripte 2 13.08.2005 11:31


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:59 Uhr.