Mun täytyisi saada koodi pysähtymään hetkeksi, mutta kuintekin niin, ettei tapahtumanlukeminen selaimessa pysähdy.
Tyylin:
for(var i = 0; i < 40;i++) { vaihdakuva(i); sleepJärkevästi(100); //tässä kohdin täytyisi siis venata. SetTimeout ei toimi, koska se laukaisee //jonkun uuden funktion, eikä sitä voi asettaa palamaan tähän kohtaan. }
Miten tämän rakenteen voisi toteuttaa javascriptillä threadin omaisesti, eli toisin sanoen käyttäjällä olisi mahdollisuus tehdä jotain muuta sillä aikaa kun kuvaa vaihdetaan(tai animaatiota pyoritetaan) eikä prosessori pelkästään odottaisi aikaa, jolloin voidaan vaihtaa kuva?
function vaihdakuva(i) { //kuvanvaihtokoodi tähän... if (i < 40) setTimeout ( "vaihdakuva(" + (i+1) + ")", 100 ); }
En ole ihan varma syntaksin oikeellisuudesta, mutta ideana itse lähtisin noin toteuttamaan.
Eli oletko nyt tekemässä funktiota, joka kutsuu itseään tuon 40 kertaa?
Yritin tätä vääntää, mutta en ole yhtään varma voiko niin tehdä?
No eihän se kutsu itseään, vaan laittaa timeoutin, joka kutsuu funktiota tietyn ajan kuluttua. Jos se kutsuisi itseään, se ei pääsisi etenemään kutsumiskohdasta, ennen kuin kutsuttu funktio on suoritettu.
Muutenkaan en oikein näe mitä hyötyä sleepsitä olisi jos sellaisen voisi toteuttaa. Javascriptihän ei ole monisäikeinen, joten sleepin aikana mitään javascriptiä ei suoritetaisi.
Kannattaa myös muistaa että javascript ei ole joku muu kieli, joten kaikkia muilla kielillä opittuja juttuja (esim. sleep) ei kannata yrittää soveltaa javascriptin kanssa.
hmmmm...eli tarkoitat että se kutsuu samaa funktiota, josta tehdään vain useita kopioita(40)? Vaiko eikö se kutsu lainkaan toista kertaa funktiota vaihdakuva?
Itse en ainakaan ymmärrä, että miten JTS:n koodi käy läpi kaikki 40 kuvaa ilman mitään silmukkaa tai jotain toisto rakennetta?
Grez kirjoitti:
Javascriptihän ei ole monisäikeinen, joten sleepin aikana mitään javascriptiä ei suoritetaisi.
Juurikin se on joskus tavoitteena. Jotkut selaimet eivät tykkää siitä, että skriptin suoritus kestää kauan, joten laittamalla taukoja setTimeout
:lla selain pysyy tyytyväisenä.
JTS:n koodi ei sellaisenaan käy läpi yhtäkään kuvaa, joudut lisäämään kutsun vaihdakuva(0)
jonnekin. Ehto (i < 40)
täytynee muuttaa muotoon (i + 1 < 40)
tai siirtää myös kuvanvaihtokoodi sen sisään.
Saattaa aiheuttaa ongelmia joillain selaimilla, mutta setTimeout
-kutsun voi kirjoittaa siistimmin setTimeout(vaihdakuva, 100, i + 1)
tai käyttämällä nimetöntä funktiota ensimmäisenä parametrina.
Mun logiikan mukaan JTS koittaa kutsua funktiossa sitä samaa funktiota ja joka kerta heittää i:tä yhden enemmän ja tämä rakenne toistuu neljään kymmeneen asti, eikö? Vai millä tavalla tämä toistorakenne saadaan tehtyä, ellei näin?
Mutta en ymmärrä, mihin oikeein parametrit sijoittuvat, koska eikö setTimeout ole muotoa setTimeout(tehtävä_joka_tehdään, sen_tietyn_ajan_kuluttua)?
niin miten siihen voi laittaa kolme parametriä
, kuten tässä
setTimeout(vaihdakuva, 100, i + 1)
tai sitten tämän (vaihdakuva(" + (i+1) + "), 100), miksi pelkkä (vaihdakuva(i+1),100) ei riitä?
Ensimmäinen parametri on joko merkkijono joka sitten annetaan eval
-funktiolle, tai funktio jota kutsutaan ilman parametreja. Jos haluaa, että sitä kusutaan joillain parametreilla, voi ne antaa setTimeout
:lle kahden ensimmäisen parametrin lisäksi. https://developer.mozilla.org/En/DOM/Window.
Paulus M kirjoitti:
miksi pelkkä (vaihdakuva(i+1),100) ei riitä?
Koska se ei tee, mitä haluat.
1) kutsu vaihdakuva(i + 1)
2) kutsu setTimeout(x, 100)
, jossa x
on ensimmäisen kutsun paluuarvo
Aivan, nyt tajusin, selkee!! Kiitoset, nyt vaan testailen!
Olis pitänyt itse browsata toi documentaatio....
EDIT:
no nyt oon käyttänyt hyväksi koodia, mutta ilmeisesti jotain on vielä pielessä. Firefoxi jää jumiin, mutta Explorer heittää virhe ilmoituksen:
Stack overflow at line: 0(ja jää sitten jumiin :D)
tässä on koodi, jos joku jaksaa vielä vaivautua:
<html> <head> </head> <body> <script language = "javascript"> function Ani() { this.animaatiot = []; } //tekee uuden animaation //animaatioden framen nimessä käytetään juoksevia numeroita. //juoksevat numerot alkavat 0001, ja jatkuu esim. 0011 ja 0142 Ani.prototype.uusi = function (nimi, lkm) { var i = this.animaatiot.length; this.animaatiot[i] = []; var nollat = "000"; //kertoo kuinka monta nollaa laitetaan kuvan nimeen. tässä tapauksessa 3. for (var j = 0; j < lkm; ++j) { if(j > 9)nollat = "00"; if(j > 99)nollat = "0"; if(j > 999) nollat = ""; this.animaatiot[i][j] = nimi + nollat + j + ".PNG"; } } var ani = new Ani(); ani.uusi("kuvat/koodarisarja/PNG", 52); kuvasarjat = new Array(); //Ladataan kaikki animaatiot puskuriin. for(var ckuvasarja = 0; ckuvasarja < ani.animaatiot.length; ckuvasarja++) { kuvasarjat[ckuvasarja] = new Array(); for(var ckuva = 0; ckuva < ani.animaatiot[ckuvasarja].length;ckuva++) { kuvasarjat[ckuvasarja][ckuva] = new Image(); kuvasarjat[ckuvasarja][ckuva].src = ani.animaatiot[ckuvasarja][ckuva]; } } //TÄSSÄ FUNKTIOSSA VIRHE TULEE function pyorita(kohta) { if(kohta < 52) { document.images[0].src= ani.animaatiot[0][kohta]; setTimeout("pyorita(" +(kohta + 1) + ")", 100); } } </script> <IMG SRC="kuvat/koodarisarja/PNG0000.PNG" BORDER="0"onload ="pyorita(0)"> </body> </html>
keksin vastauksen itse. Muistakaa tarkistaa aina, että kaikki kuvat on ladattu puskuriin ennen kuin alkaa sählää mitään, muuten tulee välillä aivan ihmeellisiä seurauksia - meni aika pitkään että sain selvitettyä ongelman.
Aihe on jo aika vanha, joten et voi enää vastata siihen.