Windows.  Virus.  Bärbara datorer.  Internet.  Kontor.  Verktyg.  Förare

Vid programmering i skriptspråk finns det periodvis ett behov av att skapa en paus - att pausa körningen av programmet ett tag och sedan fortsätta arbeta. Till exempel, i VBS- och PHP-skript är följande metoder möjliga:

VBS: wscript.sleep 1500 (stopp i 1,5 sekunder)

PHP: sömn(10); (stopp i 10 sekunder)

Under sådana pauser kan körtidssystemet (PHP eller VBS) gör ingenting. En utvecklare som försöker intuitivt använda något liknande i Javascript kommer att bli obehagligt överraskad. Ett typiskt fel när man försöker skapa en paus i Javascript ser ut så här:

Funktion badtest() ( för (var i=1; i< 10; i++) { window.setTimeout("document.getElementById("test1").value += " + i, 900) } }

Du tror att när, under loopen, turen kommer till att dra nästa nummer, kommer din setTimeout ärligt att stoppa Javascript från att fungera, vänta 0,9 sekunder, lägga till önskat nummer i slutet av inmatningsfältet och sedan fortsätta arbeta. Men i verkligheten är detta inte fallet: setInterval och setTimeout i Javascript fördröjer bara exekveringen av åtgärden (eller funktionen) som anges inom parentes. I vårt exempel kommer följande att hända:

  • i = 1;
  • fördröj att lägga till siffran "1" till inmatningsfältet med 0,9 sekunder;
  • Omedelbart efter att detta problem har ställts in fortsätter cykeln: i=2;
  • fördröj att lägga till siffran "2" till inmatningsfältet med 0,9 sekunder;
  • Betyder omedelbart t.ex. 1 ms (det vill säga oproportionerligt litet jämfört med 900 ms): slingan kommer att göra sitt arbete nästan omedelbart och skapa flera uppskjutna uppgifter från samma tidpunkt. Detta innebär att alla pågående "ritningsuppgifter" kommer att slutföras nästan samtidigt, utan pauser mellan att lägga till nya nummer. Cykeln startar; allt fryser i 0,9 s; och shirr - alla nummer skjuts i rad en efter en.

    Vad sägs om ett sådant fallär det korrekt att använda setTimeout? Det är komplicerat. Du måste anropa funktionen rekursivt(inifrån funktionen samma funktion), och så att denna process inte är oändlig, ställ in ett stoppvillkor (till exempel storleken på numret som ska skrivas ut):

    Funktion welltest() ( if (dvs< 9) { document.getElementById("test2").value += ++i window.setTimeout("welltest()", 400) } }

    Och variabeln i måste initieras utanför funktionen - till exempel så här:

    Nu fungerar allt som det ska (vi minskade fördröjningstiden från 0,9 s till 0,4 s). Men för sådana uppgifter är det mer logiskt att använda setInterval snarare än setTimeout (även om detta kommer att kräva två funktioner):

    Funktion besttest() ( window.i = 0 window.timer1 = window.setInterval("draw()", 400) ) funktion draw() ( document.getElementById("test3").value += ++i if (i >= 9) clearInterval(window.timer1) )

    Det speciella med Javascirpt setInterval-metoden är att den inte passerar "av sig själv" den måste stoppas med en speciell clearInterval-metod. Och för att göra det tydligt exakt vad som ska stoppas, tilldelas uppgiften för den uppskjutna åtgärden en speciell identifierare - en timer: window.timer1 = window.setInterval(...) .

    Identifierare kan också tilldelas uppgifter som skapats med metoden setTimeout. Alla timer-ID:n måste skilja sig från varandra (unika i det aktuella webbläsarfönstret). Sedan kan du skapa flera olika uppgifter, med uppskjutna åtgärder, och dessa uppgifter kommer att utföras parallellt (typ samtidigt, om datorn har tillräckligt med resurser), vilket i princip är omöjligt i PHP eller VBS.

    Här är ett exempel på en sida med flera Javascript-timers som körs samtidigt: setinterval.htm (Javascript fungerar i filen setinterval.js). Alla sidtimer (utom menyn) kan stoppas med Esc-tangenten. Alla exempeltimer är baserade på en "naturlig" (och inte abstrakt i++) nedräkning - tid eller avstånd. Alla "klockor" är speciellt desynkroniserade (för tydlighetens skull). Avståndsberoende timers används i "indikatorn" och i rullgardinsmenyn ("utdragbar").

    Rullgardinsmeny

    Vår glidmeny glider faktiskt (under "huvudet"): luckor lämnas speciellt mellan elementen så att du kan se hur den glider ut. Oväntat visade det sig att vi inte kunde göra lika smidiga utgångar för listor av olika längd - förmodligen på grund av låg datorprestanda ( AMD Athlon 999 MHz).

    Det är ganska uppenbart att för skönhet och harmoni är det nödvändigt att listorna med olika menyalternativ visas samtidigt. Det vill säga längre listor ska falla ut i högre hastighet, kortare vid lägre hastighet. Det verkar som att det skulle kunna implementeras så här:

  • Vi ställer in den totala "avgångstiden" till t.ex. 200 ms.
  • Om rullgardinslistan har en höjd på 20 px är det uppenbart att vi kan flytta ner den en pixel per 10 ms-intervall - och sedan om 200 ms kommer hela listan ut.
  • Om rullgardinsmenyn är 40px hög måste vi flytta den ner en pixel var 5:e ms för att få plats med samma tid.
  • Enligt denna logik, om rullgardinsmenyn är 200px hög, bör vi flytta ner den en pixel var 1 ms. Men sådan hastighet fungerar inte på vår dator - webbläsaren har helt enkelt inte tid att rita den nya positionen för listan på en millisekund. Ja. Javascript lyckas räkna (vad finns det att räkna?), men webbläsaren (Firefox) hinner inte visa. Typisk situation för webben.

    Därför är det möjligt att mer eller mindre utjämna menyns avgångstid endast med hjälp av kryckor, och det är fortfarande oklart hur detta kommer att fungera för fler snabb dator. Men vi borde väl räkna med den långsammaste? Algoritmen (utan att ta hänsyn till datorns hastighet) visar sig ungefär så här:

  • Ställ in den totala tiden för att checka ut listan: tid = 224 (ms).
  • Vi ställer in minimitiden för ett intervall i cykeln: fördröjning = 3 (ms).
  • Ställ in det lägsta steget för att flytta listan: offset = 1 (px).
  • Vi ändrar allt detta beroende på höjden på listan: 1) öka fördröjningstiden (intervall) i omvänd proportion till höjden och direkt proportionell mot den totala tidstiden (vid en höjd av 224 är koefficienten 1); 2) om höjden är större än 40 px, öka minimisteget i proportion till höjden. Konstanten "40" erhölls experimentellt för den långsammaste datorn. Tester på en Pentium 4 CPU 2,53 GHz-dator visade exakt samma siffra - 40. Annars går timers ur funktion, listor går i otakt.
  • Nu kommer listorna mer eller mindre ut. För mer eller mindre liknande tid. På sidan setinterval.htm.

    Och här kommer Bruce:

    Funktion slide_do(obj, maxtop, offset) ( if (getTopLeft(obj).top< maxtop) { obj.style.top = getTopLeft(obj).top + offset } else { if (obj && obj.timer1) { clearInterval(obj.timer1) obj.timer1 = null } } }

    Själva funktionen, som trycker ut kapslade listor från menyn, är, som vi kan se, väldigt enkel. Allt som återstår är att köra det med något i stil med denna rad:

    Ts.timer1 = setInterval(function())(slide_do(ts, maxtop, offset)), delay)

    Tja, innan du börjar, bara beräkna alla dessa maxtop och offset, och placera även listan i mintop-positionen. Detta är vad den "preliminära" slide()-funktionen på 40 rader gör. Och allt tillsammans - i filen setinterval.js. Ja, och den här skiten fungerar inte alls utan den medföljande stilfilen

    • Från:
    • Registrerad: 2014.07.08
    • Inlägg: 3 896
    • Gillar: 497
    Ämne: SetTimeOut och SetInterval, vilket är bättre att använda i JavaScript?

    SetInterval-funktionen är utformad för att köra kod flera gånger med jämna mellanrum. Det har dock ett antal nackdelar, främst olika beteende i olika webbläsare.

    Den första skillnaden är skillnaden i den tid då timern är inställd för nästa lansering. Låt oss skapa ett litet test: vi kommer att mäta hur lång tid som har gått sedan början av föregående körning och sedan dess slut.

    var d1 = new Date(), d2 = new Date(); setInterval(function() ( var d = new Date(); document.body.innerHTML += (d - d1) + " " + (d - d2) + "
    "; // Sätt ett märke i början av funktionen d1 = new Date(); while (new Date() - d1< 200); // ничего не делаем 200 миллисекунд // И в конце функции d2 = new Date(); }, 1000);

    Utgången kommer att vara informativ från den andra raden.

    I Firefox, Opera, Safari och Chrome kommer situationen att vara liknande: den första siffran kommer att vara ungefär lika med 1000, den andra - 200 mindre. Den enda skillnaden kommer att vara i spridningen av värden. Den minsta skillnaden är i Chrome och Opera.

    2 Svar av PunBB (redigerad av PunBB 2017.06.08 16:45)
    • Från: Moskva, Sovkhoznay 3, apt. 98
    • Registrerad: 2014.07.08
    • Inlägg: 3 896
    • Gillar: 497

    En annan skillnad som är mindre märkbar och svårare att återskapa, men ibland kan orsaka mycket problem, är motståndet mot systemtidsförändringar. Om du kör följande test

    setInterval(function() ( document.body.innerHTML = Math.random(); ), 500);

    Och efter lanseringen översätt systemtid för en minut sedan, i webbläsarna Firefox och Safari pausas ändringen av siffror, och efter en minut börjar den igen. Självklart är manuell översättning av systemtid en extremt sällsynt situation, men många system är konfigurerade för att automatiskt synkronisera tid med servrar på Internet, så i vissa situationer kan denna faktor inte diskonteras.

    Ännu ett litet minus setInterval-funktioner- för att kunna stoppa dess åtgärd måste du komma ihåg dess identifierare någonstans, vilket inte alltid är bekvämt.

    3 Svar från PunBB
    • Från: Moskva, Sovkhoznay 3, apt. 98
    • Registrerad: 2014.07.08
    • Inlägg: 3 896
    • Gillar: 497
    Re: SetTimeOut och SetInterval, vilket är bättre att använda i JavaScript?

    För att bli av med de listade nackdelarna med setInterval kan du använda flera setTimeout.

    Ett viktigt alternativ till setInterval är den rekursiva setTimeout:

    /** istället för: var timerId = setInterval(function() ( alert("tick"); ), 2000); */ var timerId = setTimeout(function tick() ( alert("tick"); timerId = setTimeout(tick, 2000); ), 2000);

    I koden ovan schemaläggs nästa körning omedelbart efter att den föregående är klar.

    Rekursiv setTimeout är en mer flexibel timingmetod än setInterval, eftersom tiden fram till nästa exekvering kan schemaläggas på olika sätt, beroende på resultatet av den aktuella.

    Till exempel har vi en tjänst som pollar servern efter ny data var 5:e sekund. Om servern är överbelastad kan du öka pollingintervallet till 10, 20, 60 sekunder... Och sedan returnera det när allt återgår till det normala.

    Om vi ​​regelbundet kör CPU-intensiva uppgifter, kan vi uppskatta tiden som spenderas på deras utförande och planera nästa körning tidigare eller senare.

    4 Svar från PunBB
    • Från: Moskva, Sovkhoznay 3, apt. 98
    • Registrerad: 2014.07.08
    • Inlägg: 3 896
    • Gillar: 497
    Re: SetTimeOut och SetInterval, vilket är bättre att använda i JavaScript?

    Rekursiv setTimeout garanterar en paus mellan samtal, det gör inte setInterval.

    Låt oss jämföra de två koderna. Den första använder setInterval:

    var i = 1; setInterval(function() ( func(i); ), 100);

    Den andra använder en rekursiv setTimeout:

    var i = 1; setTimeout(funktion kör() ( func(i); setTimeout(kör, 100); ), 100);

    Med setInterval avfyras den interna timern exakt var 100:e ms och anropar func(i):

    Den verkliga pausen mellan func-anrop med setInterval är mindre än vad som anges i koden!

    Detta är naturligt, eftersom drifttiden för funktionen inte tas med i beräkningen på något sätt, den "äter upp" en del av intervallet.

    Det är också möjligt att func visade sig vara mer komplex än vi förväntade oss och tog längre tid än 100 ms att köra.

    I det här fallet kommer tolken att vänta på att funktionen ska slutföras, sedan kontrollera timern och, om tiden för att anropa setInterval redan har kommit (eller passerat), kommer nästa anrop att ske omedelbart.

    Om funktionen pågår längre än setInterval-pausen kommer samtal att ske utan avbrott alls.

    5 Svar av sempai
    • Från: Jerusalem
    • Registrerad: 2015.06.02
    • Inlägg: 958
    • Gillar: 274
    Re: SetTimeOut och SetInterval, vilket är bättre att använda i JavaScript?

    Allt beror på uppgiften. Inledningsvis används SetTimeOut för att starta timern en gång, och SetInterval används för att starta en loop. Men båda funktionerna kan användas för att köra skript cykliskt om du till exempel kör dem rekursivt i SetTimeOut-funktionen, kommer de att agera nästan på samma sätt som SetInterval.

    Nackdelen med SetInterval för tillfället är att den inte tar hänsyn till exekveringstiden för själva skriptet (funktionen), och om du till exempel använder det för tunga frågor, så kommer intervalltiden att minska avsevärt, och det kan skilja sig åt i olika webbläsare.

    Men återigen, om funktionen eller begäran minimeras, är det osannolikt att slutanvändaren kommer att känna skillnaden.
    Därför är det upp till var och en att bestämma vad som ska användas.

    Det är extremt viktigt att förstå hur JavaScript-timers fungerar. Ofta matchar deras beteende inte vår intuitiva förståelse av multithreading, och detta beror på det faktum att de i verkligheten exekveras i en enda tråd. Låt oss titta på fyra funktioner som vi kan hantera timers med:

    • var id = setTimeout(fn, fördröjning); - Skapar en enkel timer som kommer att anropa en given funktion efter en given fördröjning. Funktionen returnerar ett unikt ID med vilket timern kan pausas.
    • var id = setInterval(fn, fördröjning); - Liknar setTimeout, men anropar kontinuerligt funktionen med ett specificerat intervall (tills den stoppas).
    • clearInterval(id);, clearTimeout(id); - Accepterar ett timer-ID (retursatt av en av funktionerna som beskrivs ovan) och stoppar exekvering av återuppringning"a.
    Huvudtanken att överväga är att noggrannheten för timerfördröjningsperioden inte kan garanteras. Till att börja med exekverar webbläsaren alla asynkrona JavaScript-händelser i en tråd (som musklick eller timers) och endast vid den tidpunkt då det är turen till den händelsen. Detta visas bäst med följande diagram:

    Det finns ganska mycket information att ta till sig i den här figuren, men att förstå den kommer att ge dig en djupare förståelse för hur JavaScript-asynkroni fungerar. Det här diagrammet representerar tiden vertikalt i millisekunder, de blå blocken visar block med JavaScript-kod som kördes. Till exempel exekveras det första blocket i genomsnitt på 18 ms, ett musklick blockerar exekveringen i ca 11 ms, etc.

    JavaScript kan bara exekvera en bit kod (på grund av exekveringens enkeltrådiga karaktär), som var och en blockerar exekveringen av andra asynkrona händelser. Detta innebär att när en asynkron händelse inträffar (som ett musklick, ett timeranrop eller slutförandet av en XMLHttp-begäran), läggs den till i en kö och exekveras senare (implementeringen varierar naturligtvis beroende på webbläsare, men låt oss godkänna kalla det en "kö") .

    Till att börja med, låt oss föreställa oss att två timers startar inuti ett JavaScript-block: setTimeout med en fördröjning på 10ms och setInterval med samma fördröjning. Beroende på när timern startar, kommer den att starta i det ögonblick då vi ännu inte har slutfört det första kodblocket. Observera dock att den inte tänds omedelbart (detta är inte möjligt på grund av enkel gängning). Istället ställs den uppskjutna funktionen i kö och exekveras vid nästa tillgängliga ögonblick.

    Dessutom, under körningen av det första JavaScript-blocket, sker ett musklick. Hanteraren för denna asynkrona händelse (och den är asynkron eftersom vi inte kan förutsäga den) kan inte exekveras direkt i detta ögonblick, så den hamnar också i en kö, som timern.

    Efter att det första blocket med JavaScript-kod har körts ställer webbläsaren frågan "Vad väntar på att köras?" I det här fallet är musklickshanteraren och timern i ett vänteläge. Webbläsaren väljer en av dem (klickhanteraren) och kör den. Timern väntar på nästa tillgängliga tid i exekveringskön.

    Observera att medan musklickshanteraren körs, aktiveras den första intervallåteruppringningen. Precis som timer-återuppringning kommer den att ställas i kö. Observera dock att när intervallet avfyras igen (medan timeråteruppringningen körs), kommer det att tas bort från kön. Om varje intervallåteruppringning" ställdes i kö medan en stor del av koden kördes, skulle det resultera i en massa funktioner som väntade på att bli anropade, utan några fördröjningsperioder mellan dem som avslutar exekveringen. Istället tenderar webbläsare att vänta tills det inte finns fler funktioner kvar i kön innan du lägger till ytterligare en i kön.

    Sålunda kan vi observera fallet när den tredje avfyrningen av intervallåteruppringningen sammanfaller med det ögonblick då den redan exekveras. Detta illustrerar en viktig poäng: intervaller bryr sig inte om vad som körs för närvarande, de kommer att läggas till i kön utan hänsyn till fördröjningsperioden mellan körningarna.

    Slutligen, efter att den andra intervallåteruppringningen är klar, kommer vi att se att det inte finns något kvar för JavaScript-motorn att köra. Detta innebär att webbläsaren återigen väntar på att nya asynkrona händelser ska dyka upp. Detta kommer att hända vid 50 ms, där intervallåteruppringning kommer att fungera igen. Vid det här laget kommer det inte att finnas något som blockerar det, så det kommer att fungera omedelbart.

    Låt oss titta på ett exempel som fint illustrerar skillnaden mellan setTimeout och setInterval.
    setTimeout(function())( /* Något långt kodblock... */ setTimeout(arguments.callee, 10); ), 10);
    Dessa två alternativ är likvärdiga vid första anblicken, men i verkligheten är de inte det. Kod som använder setTimeout kommer alltid att ha en fördröjning på minst 10 ms efter föregående samtal (det kan vara mer, men aldrig mindre), medan kod som använder setInterval tenderar att anropas var 10:e ms, oavsett när det föregående anropet inträffade.

    Låt oss sammanfatta allt som sägs ovan:
    - JavaScript-motorer använder en enkeltrådad miljö som omvandlar asynkrona händelser till en kö som väntar på exekvering,
    - Funktionerna setTimeout och setInterval exekveras fundamentalt olika i asynkron kod,
    - Om timern inte kan exekveras för tillfället, kommer den att fördröjas till nästa exekveringspunkt (som kommer att vara längre än den önskade fördröjningen),
    - Intervaller (setInterval) kan exekveras efter varandra utan fördröjning om deras exekvering tar längre tid än den angivna fördröjningen.

    Allt detta är extremt viktig information för utveckling. Att veta hur JavaScript-motorn fungerar, särskilt med många asynkrona händelser (vilket ofta händer), lägger en bra grund för att bygga avancerade applikationer.

    JavaScript timeout är en inbyggd javascript-funktion som exekverar en bit kod efter en angiven tidsfördröjning (i millisekunder). Detta kan vara användbart när du behöver visa en popup efter att användaren har tillbringat en tid på din sida. Eller vill du att effekten när du håller muspekaren över ett element ska starta först efter en tid? På så sätt kan du undvika att oavsiktligt utlösa en effekt om användaren svävade över den av misstag.

    Enkelt setTimeout exempel

    För att visa hur den här funktionen fungerar föreslår jag att du tar en titt på följande demo, där ett popup-fönster visas två sekunder efter att du klickat på knappen.

    Se demo

    Syntax

    MDN-dokumentationen tillhandahåller följande syntax för setTimeout:

    var timeoutID = window.setTimeout(func, ); var timeoutID = window.setTimeout(kod, );

    • timeoutID – ett numeriskt id som kan användas i kombination med clearTimeout() för att inaktivera timern;
    • func – funktion som ska köras;
    • kod (i alternativ syntax) – kodrad som ska köras;
    • fördröjning – fördröjningens varaktighet i millisekunder, varefter funktionen kommer att startas. Standardvärdet är 0.
    setTimeout vs window.setTimeout

    Ovanstående syntax använder window.setTimeout . Varför?

    Faktum är att setTimeout och window.setTimeout är praktiskt taget samma funktion. Den enda skillnaden är att i det andra uttrycket använder vi metoden setTimeout som en egenskap för det globala fönsterobjektet.

    Personligen tror jag att detta bara gör koden mycket mer komplicerad. Om vi ​​skulle definiera ett alternativ JavaScript-metoden timeout , som kunde hittas och returneras i prioriterad ordning, skulle vi stöta på ännu fler problem.

    I den här handledningen vill jag inte bråka med fönsterobjektet, men i allmänhet är det upp till dig att bestämma vilken syntax som ska användas.

    Exempel på användning

    Detta kan vara namnet på funktionen:

    function explode())( alert("Boom!"); ) setTimeout(explodera, 2000);

    Variabel som refererar till funktionen:

    var explode = function())( alert("Boom!"); ); setTimeout(explodera, 2000);

    Eller en anonym funktion:

    setTimeout(function())( alert("Boom!"); ), 2000);

    • Sådan kod är dåligt förstådd och kommer därför att vara svår att modernisera eller felsöka;
    • Det involverar användning av metoden eval() som kan vara en potentiell sårbarhet;
    • Den här metoden är långsammare än andra eftersom den kräver att JavaScript-tolken körs.

    Observera också att vi använder JavaScript-timeout-varningsmetoden för att testa koden.

    Skickar parametrar till setTimout

    I det första alternativet (och över webbläsare) skickar vi parametrar till återuppringningsfunktionen, exekveras med setTimeout.

    I följande exempel extraherar vi en slumpmässig hälsning från hälsningsarrayen och skickar den som en parameter till greet()-funktionen, som exekveras av setTimeout med en fördröjning på 1 sekund:

    function greet(greeting)( console.log(greeting); ) function getRandom(arr)( return arr; ) var greetings = ["Hej", "Bonjour", "Guten Tag"], randomGreeting = getRandom(greetings); setTimeout(function())( greet(randomGreeting); ), 1000);

    Se demo

    Alternativ metod

    I syntaxen som anges i början av artikeln finns det en annan metod med vilken du kan skicka parametrar till callback-funktionen som körs av JavaScript-timeout. Denna metod innebär utmatning av alla parametrar efter fördröjningen.

    Baserat på föregående exempel får vi:

    setTimeout(greet, 1000, randomGreeting);

    Den här metoden kommer inte att fungera i IE 9 och lägre, där de angivna parametrarna behandlas som odefinierade . Men det finns en speciell polyfill på MDN för att lösa detta problem.

    Relaterade problem och "det här"

    Koden som exekveras av setTimeout körs separat från funktionen som anropade den. På grund av detta ställs vi inför vissa problem, vars lösning kan användas nyckelord detta.

    var person = ( firstName: "Jim", introduce: function())( console.log("Hej, jag är " + this.firstName); ) ); person.introduce(); // Utgångar: Hej, jag " m Jim setTimeout(person.introduce, 50); // Utgångar: Hej, jag är odefinierad

    Anledningen till denna utdata är att i det första exemplet pekar detta på personobjektet, och i det andra exemplet pekar det på det globala fönsterobjektet, som inte har en firstName-egenskap.

    För att bli av med denna inkonsekvens kan du använda flera metoder:

    Tvinga detta att ställas in

    Detta kan göras med bind(), en metod som skapar ny funktion, som när den anropas använder ett specifikt värde som värdet på denna nyckel. I vårt fall invänder den angivna personen. Detta ger oss i slutändan:

    setTimeout(person.introduce.bind(person), 50);

    Obs: bindningsmetoden introducerades i ECMAScript 5, vilket betyder att den bara fungerar i moderna webbläsare. I andra, när du använder det, kommer du att få ett JavaScript-exekveringsfel "function timeout error".

    Använd biblioteket

    Många bibliotek har inbyggda funktioner som behövs för att lösa detta problem. Till exempel metoden jQuery.proxy(). Den tar en funktion och returnerar en ny som alltid kommer att använda ett specifikt sammanhang. I vårt fall kommer sammanhanget att vara:

    setTimeout($.proxy(person.introducera, person), 50);

    Se demo

    Inaktiverar timern

    Returvärdet för setTimeout är ett numeriskt id som kan användas för att inaktivera timern med funktionen clearTimeout():

    var timer = setTimeout(myFunction, 3000); clearTimeout(timer);

    Låt oss se det i aktion. I följande exempel, om du klickar på knappen "Starta nedräkning", kommer nedräkningen att börja. När det är klart kommer kattungarna att få sina. Men om du klickar på "Stoppa nedräkning"-knappen stoppas JavaScript-timeout-timern och återställs.

    Se exempel

    Låt oss sammanfatta det

    setTimeout är en asynkron funktion, vilket innebär att det resulterande anropet till denna funktion går in i en kö och kommer att exekveras först efter att alla andra åtgärder på stacken har slutförts. Det kan inte köras samtidigt med andra funktioner eller en separat tråd.

    Metoden setInterval() som erbjuds på gränssnitten Window och Worker, anropar en funktion upprepade gånger eller exekverar ett kodavsnitt, med en fast tidsfördröjning mellan varje anrop.

    Den returnerar ett intervall-ID som unikt identifierar intervallet, så att du kan ta bort det senare genom att anropa clearInterval() . Denna metod definieras av WindowOrWorkerGlobalScope mixin. Syntax = var intervalID omfattning .setInterval(, func, [dröjsmål, arg1, ...]); Syntax = var intervalID omfattning arg2, func koda ); Parametrar func En funktion som ska utföras varje fördröjning millisekunder. Funktionen skickas inte över några argument och inget returvärde förväntas. kod En valfri syntax låter dig inkludera en sträng istället för en funktion, som kompileras och exekveras varje fördröjning millisekunder. Denna syntax är rekommenderas inte .setInterval( för

    samma skäl som gör användningen av eval() till en säkerhetsrisk. fördröjning Tiden, i millisekunder (tusendelar av en sekund), timern bör fördröja mellan exekvering av den specificerade funktionen eller koden. Se nedan för detaljer om det tillåtna intervallet för fördröjningsvärden. arg1, ..., argN Valfritt Ytterligare argument som skickas vidare till funktionen specificerad av

    när timern går ut.

    Obs: Att skicka ytterligare argument till setInterval() i den första syntaxen fungerar inte i

    Internet Explorer

    9 och tidigare. Om du vill aktivera denna funktionalitet i den webbläsaren måste du använda en polyfill (se avsnittet).

    Returvärde

    Det returnerade intervalID är ett numeriskt värde som inte är noll som identifierar timern som skapas av anropet till setInterval() ; detta värde kan skickas för att avbryta timeout. Det kan vara bra att vara medveten om att setInterval() och setTimeout() delar samma pool av ID:n och att clearInterval() och clearTimeout() tekniskt sett kan användas omväxlande. För tydlighetens skull bör du dock försöka att alltid matcha dem för att undvika förvirring när du underhåller din kod.

    Obs: Fördröjningsargumentet konverteras till ett signerat 32-bitars heltal. Detta begränsar effektivt fördröjningen till 2147483647 ms, eftersom det är specificerat som ett signerat heltal i IDL.

    Exempel Exempel 1: Grundläggande syntax

    Följande

    setInterval/clearInterval exempel var nIntervId;

    function changeColor() ( nIntervId = setInterval(flashText, 1000); ) funktion flashText() ( var oElem = document.getElementById("my_box"); oElem.style.color = oElem.style.color == "röd" ? " blue" : "red"; // oElem.style.color == "red" ? "blue" : "red" är en ternär operator. ) funktion stopTextColor() ( clearInterval(nIntervId); )

    Hej världen

    Stopp

    Exempel 3: Skrivmaskinsimulering

    Följande exempel simulerar skrivmaskin genom att först rensa och sedan långsamt skriva innehåll i NodeList som matchar en angiven grupp av väljare.< nPos) { return true; } var oRel, bExit = false; if (aMap.length === nPos) { aMap.push(0); } while (aMap < oSheet.parts.length) { oRel = oSheet.parts]; scroll(oRel, nPos + 1, bEraseAndStop) ? aMap++ : bExit = true; if (bEraseAndStop && (oRel.ref.nodeType - 1 | 1) === 3 && oRel.ref.nodeValue) { bExit = true; oCurrent = oRel.ref; sPart = oCurrent.nodeValue; oCurrent.nodeValue = ""; } oSheet.ref.appendChild(oRel.ref); if (bExit) { return false; } } aMap.length--; return true; } function typewrite () { if (sPart.length === 0 && scroll(aSheets, 0, true) && nIdx++ === aSheets.length - 1) { clean(); return; } oCurrent.nodeValue += sPart.charAt(0); sPart = sPart.slice(1); } function Sheet (oNode) { this.ref = oNode; if (!oNode.hasChildNodes()) { return; } this.parts = Array.prototype.slice.call(oNode.childNodes); for (var nChild = 0; nChild < this.parts.length; nChild++) { oNode.removeChild(this.parts); this.parts = new Sheet(this.parts); } } var nIntervId, oCurrent = null, bTyping = false, bStart = true, nIdx = 0, sPart = "", aSheets = , aMap = ; this.rate = nRate || 100; this.play = function () { if (bTyping) { return; } if (bStart) { var aItems = document.querySelectorAll(sSelector); if (aItems.length === 0) { return; } for (var nItem = 0; nItem < aItems.length; nItem++) { aSheets.push(new Sheet(aItems)); /* Uncomment the following line if you have previously hidden your elements via CSS: */ // aItems.style.visibility = "visible"; } bStart = false; } nIntervId = setInterval(typewrite, this.rate); bTyping = true; }; this.pause = function () { clearInterval(nIntervId); bTyping = false; }; this.terminate = function () { oCurrent.nodeValue += sPart; sPart = ""; for (nIdx; nIdx < aSheets.length; scroll(aSheets, 0, false)); clean(); }; } /* usage: */ var oTWExample1 = new Typewriter(/* elements: */ "#article, h1, #info, #copyleft", /* frame rate (optional): */ 15); /* default frame rate is 100: */ var oTWExample2 = new Typewriter("#controls"); /* you can also change the frame rate value modifying the "rate" property; for example: */ // oTWExample2.rate = 150; onload = function () { oTWExample1.play(); oTWExample2.play(); }; span.intLink, a, a:visited { cursor: pointer; color: #000000; text-decoration: underline; } #info { width: 180px; height: 150px; float: right; background-color: #eeeeff; padding: 4px; overflow: auto; font-size: 12px; margin: 4px; border-radius: 5px; /* visibility: hidden; */ }

    JavaScript-skrivmaskin - MDN Exempelfunktion Skrivmaskin (sSelector, nRate) ( funktion ren () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) funktionsrullning (oSheet, nPos , bEraseAndStop) ( if (!oSheet.hasOwnProperty("delar") || aMap.length

    CopyLeft 2012 av Mozilla Developer Network

    [ Spela | Pausa | Avsluta ]

    Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Pellentesque placerat enim at lacus ultricies vitae facilisis nisi fringilla. I tincidunt tincidunt tincidunt.

    JavaScript skrivmaskin
    Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sitt amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, vid ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Heltal ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Maecenas vestibulum mollis nunc i posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.

    Duis lobortis sapien quis nisl luctus porttitor. I tempor semper libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida nec. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae quam elit. Donec dignissim est in quam tempor consequat. Aliquam aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus risus, dignissim et fringilla et, egestas vel eros. Duis malesuada accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing ultricies fermentum. Praesent bibStartum condimentum feugiat.

    Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc, vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis. Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc. Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl eu sem vehicula egestas.

    Återuppringningsargument

    Som tidigare diskuterats stöder inte Internet Explorer version 9 och nedan överföring av argument till callback-funktionen i varken setTimeout() eller setInterval() . Följande IE-specifik kod visar en metod för att övervinna denna begränsning. För att använda, lägg helt enkelt till följande kod överst i ditt skript.

    /*\ |*| |*| IE-specifik polyfill som möjliggör överföring av godtyckliga argument till |*| callback-funktioner för javascript-timers (HTML5 standardsyntax)..setInterval |*| https://site/User:fusionchess |*| |*| Syntax: |*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(kod, fördröjning); |*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); |*| var intervalID = window.setInterval(kod, fördröjning); |*| \*/ if (document.all && !window.setTimeout.isPolyfill) ( var __nativeST__ = window.setTimeout; window.setTimeout = funktion (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array .prototype.slice.call(arguments, 2); return __nativeST__(vCallback-instans av funktion () ( vCallback.apply(null, aArgs); ): vCallback, nDelay ); ( var __nativeSI__ = window.setInterval; window.setInterval = funktion (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array.prototype. slice.call(arguments, 2); return __nativeSI__(vCallback instans av funktion () ( vCallback.apply(null, aArgs); ): vCallback, nDelay );

    En annan möjlighet är att använda en anonym funktion för att ringa din återuppringning, även om denna lösning är lite dyrare. Exempel:

    Var intervalID = setInterval(function() ( myFunc("en", "två", "tre"); ), 1000);

    var intervalID = setInterval(function(arg1) ().bind(undefined, 10), 1000);

    Inaktiva flikar kräver Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

    Från och med Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) kläms intervallen fast för att inte avfyras oftare än en gång per sekund i inaktiva flikar.

    "det här" problemet

    När du skickar en metod till setInterval() eller någon annan funktion anropas den med fel detta värde. Det här problemet förklaras i detalj i JavaScript-referensen.

    Förklaring

    MyArray = ["noll", "en", "två"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); myArray.myMethod(); // skriver ut "noll,ett,två" myArray.myMethod(1); // skriver ut "one" setTimeout(myArray.myMethod, 1000); // skriver ut "" efter 1 sekund setTimeout(myArray.myMethod, 1500, "1"); // skriver ut "odefinierad" efter 1,5 sekunder // att skicka "detta" objektet med .call kommer inte att fungera // eftersom detta kommer att ändra värdet på detta inuti själva setTimeout // medan vi vill ändra värdet på detta inuti myArray .myMethod // i själva verket kommer det att vara ett fel eftersom setTimeout-koden förväntar sig att detta är fönsterobjektet: setTimeout.call(myArray, myArray.myMethod, 2000 // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative-prototype); setTimeout.call(myArray, myArray.myMethod, 2500, 2); // samma fel

    Som du kan se finns det inga sätt att skicka detta objekt till återuppringningsfunktionen i det äldre JavaScript.

    En möjlig lösning

    Ett möjligt sätt att lösa "detta"-problemet är att ersätta de två inbyggda setTimeout() eller setInterval() globala funktionerna med två icke-infödd de som möjliggör deras anrop genom metoden Function.prototype.call. Följande exempel visar en möjlig ersättning:

    // Aktivera passage av "detta" objekt genom JavaScript-timers var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = funktion (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback-instans av funktion ? funktion () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay ); window.setInterval = funktion (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback-instans av funktion ? funktion () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay );

    Dessa två ersättningar möjliggör också HTML5-standardpassage av godtyckliga argument till återuppringningsfunktionerna för timers i IE. Så de kan användas som icke-standardkompatibel polyfills också. Se för a standard polyfill.

    Nytt funktionstest:

    MyArray = ["noll", "en", "två"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(alert, 1500, "Hej världen!"); // standardanvändningen av setTimeout och setInterval bevaras, men... setTimeout.call(myArray, myArray.myMethod, 2000); // skriver ut "zero,one,two" efter 2 sekunder setTimeout.call(myArray, myArray.myMethod, 2500, 2); // skriver ut "två" efter 2,5 sekunder

    För en mer komplex men ändå modulär version av den ( Demon) se JavaScript Daemons Management. Denna mer komplexa version är inget annat än en stor och skalbar samling metoder för Demon konstruktör. Men den Demon konstruktorn i sig är inget annat än en klon av MiniDaemon med ett extra stöd för init och start funktioner som deklarerades under instansieringen av demon. Så den MiniDaemon ramverk förblir det rekommenderade sättet för enkla animationer , eftersom Demon utan dess samling av metoder är i huvudsak en klon av det.

    minidaemon.js /*\ |*| |*| :: MiniDaemon:: |*| |*| Revision #2 - 26 september 2014.setInterval |*| https://site/User:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| Detta ramverk släpps under GNU Lesser General Public License, version 3 eller senare. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ function MiniDaemon (oOwner, fTask, nRate, nLen) ( if (!(denna && denna instans av MiniDaemon)) ( return; ) if (arguments.length< 2) { throw new TypeError("MiniDaemon - not enough arguments"); } if (oOwner) { this.owner = oOwner; } this.task = fTask; if (isFinite(nRate) && nRate >0) ( this.rate = Math.floor(nRate); ) if (nLen > 0) ( this.length = Math.floor(nLen); ) ) MiniDaemon.prototype.owner = null; MiniDaemon.prototype.task = null; MiniDaemon.prototype.rate = 100; MiniDaemon.prototype.length = Oändlighet;< 1: this.INDEX + 1 >denna.längd; ); MiniDaemon.prototype.synchronize = function () ( if (this.PAUSED) ( return; ) clearInterval(this.SESSION); this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this); ); MiniDaemon.prototype.pause = funktion () ( clearInterval(this.SESSION); this.PAUSED = true; ); MiniDaemon.prototype.start = funktion (bReverse) ( var bBackw = Boolean(bReverse); if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) ( return; ) this.BACKW = bBackw; this.PAUSED = false this.synchronize();

    MiniDaemon skickar argument till återuppringningsfunktionen. Om du vill arbeta med det med webbläsare som inte stöder den här funktionen, använd en av metoderna som föreslagits ovan.

    Syntax

    var myDaemon = new MiniDaemon( detta Objekt, återuppringning[ , hastighet [, längd]]);

    Beskrivning Användningsanteckningar

    Funktionen setInterval() används vanligtvis för att ställa in en fördröjning för funktioner som körs om och om igen, till exempel animationer. Du kan avbryt intervallet med WindowOrWorkerGlobalScope.clearInterval() .

    Om du vill ha din funktion anropad en gång efter den angivna fördröjningen, använd .

    Fördröjningsbegränsningar

    Det är möjligt för intervaller att kapslas; det vill säga återuppringningen för setInterval() kan i sin tur anropa setInterval() för att starta ett annat intervall som körs, även om det första fortfarande pågår. För att mildra den potentiella inverkan detta kan ha på prestanda, när intervallen är kapslade över fem nivåer djupa, kommer webbläsaren automatiskt att tvinga fram ett minimivärde på 4 ms för intervallet. Försök att ange ett värde mindre än 4 ms i djupt kapslade anrop till setInterval() kommer att fästas till 4 ms.

    Webbläsare kan tvinga fram ännu strängare minimivärden för intervallet under vissa omständigheter, även om dessa inte borde vara vanliga. Observera också att den faktiska tid som går mellan samtalen till återuppringningen kan vara längre än den givna fördröjningen; Se Orsaker till förseningar längre än vad som anges i WindowOrWorkerGlobalScope.setTimeout() för exempel.

    Se till att exekveringstiden är kortare än intervallfrekvensen

    Om det finns en möjlighet att din logik kan ta längre tid att exekvera än intervalltiden, rekommenderas att du anropar en namngiven funktion rekursivt med setTimeout() . Till exempel, om du använder setInterval() för att polla en fjärrserver var 5:e sekund, kan nätverkslatens, en server som inte svarar och en mängd andra problem hindra begäran från att slutföras inom den tilldelade tiden. Som sådan kan du hitta dig själv med köade XHR-förfrågningar som inte nödvändigtvis kommer tillbaka i ordning.



    Om du upptäcker ett fel markerar du ett textstycke och trycker på Ctrl+Enter
    DELA: