Internet Windows Android
Kengaytirish

Javascript bir nechta intervalli taymerlarning bir vaqtning o'zida ishlashiga to'sqinlik qiladi. Javascriptdagi taymerlar (setInterval, setTimeout)

JavaScript taymut - bu ma'lum bir vaqt kechikishidan keyin (millisekundlarda) kod qismini bajaradigan javascriptning mahalliy funktsiyasi. Foydalanuvchi sizning sahifangizda biroz vaqt o'tkazgandan so'ng, qalqib chiquvchi oynani ko'rsatish kerak bo'lganda, bu foydali bo'lishi mumkin. Yoki siz kursorni elementga bir muncha vaqt o'tgach, ta'sir boshlanishini xohlaysiz. Shunday qilib, agar foydalanuvchi tasodifan yiqilib tushsa, siz tasodifan ta'sir qilishining oldini olishingiz mumkin.

SetTimeout oddiy misoli

Bu funksiyaning ta'sirini ko'rsatish uchun men tugma bosilganidan ikki soniya o'tgach, ochiladigan oyna paydo bo'ladigan quyidagi demoni ko'rib chiqishni taklif qilaman.

Demoni ko'rish

Sintaksis

MDN hujjatlari setTimeout uchun quyidagi sintaksisini beradi:

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

  • timeoutID - bu taymerni o'chirish uchun clearTimeout () bilan birgalikda ishlatilishi mumkin bo'lgan raqamli identifikator;
  • func - bajariladigan funksiya;
  • kod ( muqobil sintaksisda) - bajariladigan kod qatori;
  • kechikish - millisekundlarda kechikish davomiyligi, undan keyin funksiya ishga tushadi. Standart - 0.

setTimeout va boshqalar window.setTimeout

Yuqoridagi sintaksisda window.setTimeout ishlatiladi. Nima uchun?

Aslida, setTimeout va window.setTimeout deyarli bir xil funktsiyadir. Faqatgina farq shundaki, ikkinchi bayonotda biz setTimeout usulini global oyna ob'ektining xususiyati sifatida ishlatamiz.

Shaxsan menimcha, bu kodni ancha murakkablashtiradi. Agar biz muqobil tartibda topilishi va qaytarilishi mumkin bo'lgan muqobil JavaScript taymut usulini aniqlasak, biz bundan ham katta muammolarga duch kelamiz.

Bu darslikda men deraza obyekti bilan aralashishni xohlamayman, lekin umuman qaysi sintaksisdan foydalanishni o'zingiz hal qilasiz.

Foydalanish misollari

Bu funktsiyaning nomi bo'lishi mumkin:

funksiya explode () (ogohlantirish ("Boom!");) setTimeout (portlash, 2000);

Funktsiyaga tegishli o'zgaruvchi:

var explode = function () (ogohlantirish ("Boom!");); setTimeout (portlash, 2000);

Yoki anonim funksiya:

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

  • Bunday kod yaxshi tushunilmagan, shuning uchun uni modernizatsiya qilish yoki disk raskadrovka qilish qiyin bo'ladi;
  • Bu mumkin bo'lgan zaiflik bo'lishi mumkin bo'lgan eval () usulini qo'llashni o'z ichiga oladi;
  • Bu usul boshqalarga qaraganda sekinroq, chunki u ishlashi kerak JavaScript tarjimoni.

Shuni ham yodda tutingki, biz kodni sinab ko'rish uchun JavaScript tugashi uchun ogohlantirish usulidan foydalanmoqdamiz.

Parametrlarni setTimout -ga o'tkazish

Birinchisida ( Bundan tashqari, o'zaro faoliyat brauzer) varianti, biz parametrlarni setTimeout yordamida bajarilgan qayta qo'ng'iroq qilish funktsiyasiga o'tkazamiz.

Quyidagi misolda biz salomlashish qatoridan tasodifiy salomni ajratib olamiz va uni 1 soniya kechikish bilan setTimeout tomonidan bajariladigan salom () funktsiyasiga parametr sifatida o'tkazamiz:

funktsiya salomlashish (salomlashish) (console.log (salomlashish);) funktsiyasi getRandom (arr) (qaytish arr;) var salomlar = ["Salom", "Bonjour", "Guten Tag"], randomGreeting = getRandom (salomlar); setTimeout (function () (salomlashish (randomGreeting);), 1000);

Demoni ko'rish

Muqobil usul

Maqolaning boshidagi sintaksisda JavaScript tugashi bilan bajariladigan qayta qo'ng'iroq qilish funktsiyasiga parametrlarni uzatishning boshqa usuli mavjud. Bu usul kechiktirilgandan so'ng barcha parametrlarning chiqishini bildiradi.

Oldingi misolga asoslanib, biz quyidagilarni olamiz:

setTimeout (salom, 1000, randomGreeting);

Bu usul IE 9 va undan pastda ishlamaydi, bu erda o'tgan parametrlar aniqlanmagan. Ammo bu muammoni hal qilish uchun MDN maxsus polifillaga ega.

Tegishli muammolar va "bu"

SetTimeout tomonidan bajarilgan kod uni chaqirgan funktsiyadan alohida ishlaydi. Shu sababli, biz ma'lum muammolarga duch kelmoqdamiz, bu kalit so'zni yechim sifatida ishlatish mumkin.

var person = (firstName: "Jim", joriy etish: function () (console.log ("Salom, men" m "+ this.firstName);)); person.introduce (); // Chiqishlar: Salom, men" m Jim setTimeout (shaxs.tanish, 50); // Chiqish: Salom, men aniqlanmaganman

Bu xulosaning sababi shundaki, bu birinchi misolda shaxs ob'ektiga olib keladi, ikkinchi misolda esa birinchi oyna xususiyatiga ega bo'lmagan global oyna ob'ektini ko'rsatadi.

Bu nomuvofiqlikni bartaraf etish uchun siz bir necha usullardan foydalanishingiz mumkin:

Ushbu qiymatni o'rnatishga majbur qiling

Buni bind () yordamida amalga oshirish mumkin, bu yangi funktsiyani yaratadi, u kalitning qiymati deb atalganda ma'lum qiymatdan foydalanadi. Bizning holatda, ko'rsatilgan shaxs e'tiroz bildiradi. Bu bizga natija beradi:

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

Eslatma: Bog'lanish usuli ECMAScript 5 da joriy qilingan, ya'ni u faqat zamonaviy brauzerlarda ishlaydi. Boshqalarda, siz uni qo'llaganingizda ish vaqti xatosini olasiz JavaScript -ni "funktsiya tugashi bilan bog'liq xato".

Kutubxonadan foydalaning

Ko'p kutubxonalarda bu muammoni hal qilish uchun zarur bo'lgan o'rnatilgan funktsiyalar mavjud. Masalan, jQuery.proxy () usuli. U funktsiyani oladi va yangisini qaytaradi, bunda u har doim ma'lum bir kontekstdan foydalanadi. Bizning holatda, kontekst quyidagicha bo'ladi.

setTimeout ($. proksi (person.introduction, person), 50);

Demoni ko'rish

Taymerni o'chirib qo'yish

SetTimeout -ning qaytish qiymati - bu taymerni o'chirish uchun clearTimeout () funktsiyasi yordamida ishlatilishi mumkin bo'lgan raqamli identifikator:

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

Keling, buni amalda ko'rib chiqaylik. Keyingi misolda, agar siz tugmani bosgan bo'lsangiz " Ortga hisoblashni boshlash", Geri hisoblash boshlanadi. Bu tugagandan so'ng, mushukchalar o'zlarini olishadi. Ammo agar siz tugmani bosgan bo'lsangiz " Ortga hisoblashni to'xtating", JavaScript vaqti tugashi to'xtatiladi va tiklanadi.

Misolni ko'rish

Xulosa qilaylik

setTimeout - bu asinxron funktsiya, ya'ni bu funktsiyaga qabul qilingan chaqiruv navbatga qo'yiladi va faqat boshqa barcha harakatlar bajarilgandan so'ng bajariladi. U boshqa funktsiyalar yoki alohida oqim bilan bir vaqtda ishlay olmaydi.

The setInterval () Window va Worker interfeyslarida taklif qilingan usul har bir qo'ng'iroq o'rtasida ma'lum vaqt kechiktirilishi bilan funktsiyani qayta -qayta chaqiradi yoki kod parchasini bajaradi. U intervalni aniq belgilaydigan intervalli identifikatorni qaytaradi, shuning uchun uni keyinchalik clearInterval () ga qo'ng'iroq qilib olib tashlashingiz mumkin. Bu usul WindowOrWorkerGlobalScope aralashmasi bilan belgilanadi.

Sintaksis

var intervalID = qamrov.setInterval ( kulgili, kechikish, [arg1, arg2, ...]); var intervalID = qamrov.setInterval ( kod, kechikish);

Parametrlar

func Har bir millisekundda kechiktirib bajariladigan funksiya. Funktsiya hech qanday dalillarni uzatmaydi va qaytarish qiymati kutilmaydi. kod Ixtiyoriy sintaksis har bir millisekundda tuzilgan va bajariladigan funksiya o'rniga qatorni qo'shishga imkon beradi. Bu sintaksis tavsiya qilinmaydi eval () dan foydalanishni xavfsizlik xavfiga olib keladigan bir xil sabablarga ko'ra. kechikish Vaqt, millisekundlarda (sekundning mingdan bir qismi), taymer belgilangan funksiya yoki kodni bajarilishi o'rtasida kechikishi kerak. Ruxsat etilgan kechikish qiymatlari diapazoni haqida batafsil ma'lumotni quyida ko'ring. arg1, ..., argN ixtiyoriy tomonidan ko'rsatilgan funktsiyaga o'tkaziladigan qo'shimcha argumentlar kulgili taymer muddati tugashi bilan.

Eslatma: Birinchi sintaksisda setInterval () ga qo'shimcha argumentlarni o'tkazish Internet Explorer 9 va undan oldingi versiyalarda ishlamaydi. Agar siz ushbu funktsiyani o'sha brauzerda yoqishni xohlasangiz, polifilladan foydalanishingiz kerak (bo'limga qarang).

Qaytish qiymati

Qaytgan intervalID-raqamli, nolga teng bo'lmagan qiymat, bu setInterval () ga qo'ng'iroq tomonidan yaratilgan taymerni aniqlaydi; vaqtni bekor qilish uchun bu qiymatga o'tish mumkin.

SetInterval () va setTimeout () bir xil identifikatorlar havzasini bo'lishishini bilish foydali bo'lishi mumkin va clearInterval () va clearTimeout () texnik jihatdan bir -birining o'rnida ishlatilishi mumkin. Aniqlik uchun, kodingizni saqlashda chalkashliklarga yo'l qo'ymaslik uchun siz ularni har doim moslashtirishga harakat qilishingiz kerak.

Eslatma: Kechiktirish argumenti imzolangan 32-bitli butun songa aylantiriladi. Bu kechiktirishni 2147483647 msgacha samarali cheklaydi, chunki u IDLda imzolangan tamsayı sifatida ko'rsatilgan.

Misollar

1 -misol: Asosiy sintaksis

Quyidagi misol setInterval () ning asosiy sintaksisini ko'rsatadi.

Var intervalID = window.setInterval (myCallback, 500, "1 -parametr", "2 -parametr"); myCallback (a, b) funktsiyasi (// Sizning kodingiz bu erda // Parametrlar faqat ixtiyoriy.console.log (a); console.log (b);)

2 -misol: Ikkita rangni almashtirish

Quyidagi misol Stopte tugmasi bosilmaguncha sekundiga bir marta fleshtext () funktsiyasini chaqiradi.

setInterval / clearInterval misoli

Salom Dunyo

3 -misol: yozuv mashinkasini simulyatsiyasi

Quyidagi misol yozuv mashinkasini simulyatsiya qiladi, so'ngra NodeList -ga belgilangan selektorlar guruhiga mos keladigan tarkibni asta -sekin o'chirib tashlaydi.

JavaScript yozuv mashinasi - MDN misoli

CopyLeft 2012 Mozilla Developer Network tomonidan

[ O'ynang | To'xtatish | Tugatish ]

Vivamus blandit massa ut metus mattis fringilla lektus imperdiet. Proin ac ante a felis ornare avtomobil. Qisqichbaqasimon lacus vitae eros convallis ut mollis magna pellentesque. Percelles lacus ultracies vitae facilisis nisi fringilla uchun eng yaxshi joy. Tincidunt tincidunt tincidunt.

JavaScript yozuv mashinkasi

Lorem ipsum dolor o'tirib, elit adipiscing konsectetur. Ullamcorper - bu ulamcorper. To'xtatib turadigan narsalar, auctor auctor mollis sed, malesuada condimentum magna. Quisque ante tellusda, yo'ldoshda. Pellentesque turistlar senectus et netus va malesuada mashhur turbis egestas. Meni mag'lubiyatga uchratmang. Etiam o'tiradigan joy - bu auktor emas, balki faucibus ante. Mauris vel consectetur dolor. Yopish -to'kilmasligi kerak bo'lgan eng muhim narsa. O'ylab ko'ring -chi, axlatni tortib oling, qiynoqqa soling. Phasellus adipiscing fermentum nibh ac commodo. Nom turpis, bu kasallikka chalingan odam emas, balki o'z navbatida.

Phasellus nisbiy lorem:

Duis lobortis sapien quis nisl luctus porttitor. Vaqt o'tishi bilan, men hech qachon o'ylamayman. Bu, albatta, rhoncus non diam emas. Morbi auktor ornare orci, euismod felis gravida nec. O'chirishning asosiy elementi - bu erga tegmaslik. Qisqartirilgan ma'lumotlarning bir xilligi. Bu juda yaxshi. Bu vaqtinchalik natija emas. Aliquam aliquam diam non felis convallis suscipit. Nulla qulayligi. Qishloq xo'jayinlari va boshqalar. Duis malesuada accumban dui, at fringilla mauris bibStartum quis. Achchiq fermentlar. Boshlang'ich bant

Namlik, ligula eu fringilla pulvinar, lektus tellus iaculis nunc, meta leo non metus. Proint mattis lobortis lobortis. Quicque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor o'tir, elitni tanlab ol. Xotirani ozod qiling. Nullam tortor nunc, elementes a consectetur va ultrices, eu orci. Lorem ipsum dolor o'tirib, elit adipiscing konsectetur. Pellentesque a nisl eu sem avtomobicula egestas.

Qayta qo'ng'iroq qilish argumentlari

Yuqorida aytib o'tilganidek, Internet Explorer 9 va undan keyingi versiyalari qayta qo'ng'iroq qilish funktsiyasiga argumentlarni setTimeout () yoki setInterval () da uzatishni qo'llab -quvvatlamaydi. Quyidagi IE-ga xos kod bu cheklovni bartaraf etish usulini ko'rsatadi. Foydalanish uchun skriptning yuqori qismiga quyidagi kodni qo'shing.

/ * \ | * | | * | | * | Ga ixtiyoriy argumentlarni o'tishga imkon beruvchi IE-ga xos bo'lgan ko'p to'ldirish javascript taymerlarining qayta qo'ng'iroq qilish funktsiyalari (HTML5 standart sintaksisi) .. setInterval | * | https: // sayt / Foydalanuvchi: fusionchess | * | | * | Sintaksis: | * | var timeoutID = window.setTimeout (func, delay [, arg1, arg2, ...]); | * | var timeoutID = window.setTimeout (kod, kechikish); | * | var intervalID = window.setInterval (func, delay [, arg1, arg2, ...]); | * | var intervalID = window.setInterval (kod, kechikish); | * | \ * / if (document.all &&! window.setTimeout.isPolyfill) (var __nativeST__ = window.setTimeout; window.setTimeout = funktsiya (vCallback, nDelay / *, argumentToPass1, argumentToPass2 va boshqalar * /) (var aArgs = Array .prototype.slice.call (argumentlar, 2); __nativeST __ (funksiyaning vCallback misoli funksiyasi) () vCallback.apply (null, aArgs);): vCallback, nDelay);); window.setTimeout.isPolyfill = rost; ) agar (document.all &&! window.setInterval.isPolyfill) (var __nativeSI__ = window.setInterval; window.setInterval = funktsiya (vCallback, nDelay / *, argumentToPass1, argumentToPass2, va hokazo * /) slice.call (argumentlar, 2); __nativeSI __ (funktsiyani vCallback misoli?) (vCallback.apply (null, aArgs);): vCallback, nDelay);); window.setInterval.isPolyfill = rost;)

Yana bir variant - bu qayta qo'ng'iroq qilish uchun anonim funktsiyadan foydalanish, lekin bu yechim biroz qimmatroq. Misol:

Var intervalID = setInterval (function () (myFunc ("bir", "ikki", "uch");), 1000); var intervalID = setInterval (funktsiya (arg1) () .bind (aniqlanmagan, 10), 1000);

Faol bo'lmagan varaqlar

Gecko 5.0 talab qilinadi (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) dan boshlab, faol bo'lmagan oynalarda sekundiga bir martadan ko'p bo'lmagan vaqt oralig'i yopiladi.

"Bu" muammosi

Agar usulni setInterval () yoki boshqa funktsiyaga o'tkazsangiz, u noto'g'ri bu qiymat bilan chaqiriladi. Bu muammo JavaScript havolasida batafsil tushuntirilgan.

Tushuntirish

SetInterval () tomonidan bajarilgan kod, u chaqirilgan funktsiyadan ko'ra, alohida ijro kontekstida ishlaydi. Natijada, chaqirilgan funktsiya uchun kalit so'z oyna (yoki global) ob'ektiga o'rnatiladi, bu setTimeout deb nomlangan funktsiya uchun bir xil emas. Quyidagi misolga qarang (setInterval () o'rniga setTimeout () dan foydalaniladi - muammo, har ikkala taymer uchun ham bir xil):

MyArray = ["nol", "bir", "ikki"]; myArray.myMethod = funktsiyasi (sProperty) (ogohlantirish (argumentlar.length> 0? bu: bu);); myArray.myMethod (); // "nol, bir, ikkita" ni bosib chiqaradi myArray.myMethod (1); // "bitta" setTimeout -ni chop etadi (myArray.myMethod, 1000); // 1 soniya setTimeoutdan keyin "" ni bosib chiqaradi (myArray.myMethod, 1500, "1"); // "aniqlanmagan" ni 1,5 soniyadan keyin bosib chiqaradi // "bu" ob'ektini .call bilan ishlash ishlamaydi // chunki bu setTimeout ichidagi qiymatini o'zgartiradi // biz bu qiymatni myArray ichidan o'zgartirmoqchimiz. .myMethod // aslida xato bo'ladi, chunki setTimeout kodi deraza obyekti bo'lishini kutadi: setTimeout.call (myArray, myArray.myMethod, 2000); // xato: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: WrappedNative prototipidagi noqonuniy operatsiya" setTimeout.call (myArray, myArray.myMethod, 2500, 2); // bir xil xato

Ko'rib turganingizdek, bu ob'ektni eski JavaScript -da qayta qo'ng'iroq qilish funktsiyasiga o'tkazishning hech qanday usuli yo'q.

Mumkin bo'lgan yechim

"Bu" muammoni hal qilishning mumkin bo'lgan usuli - bu ikkita mahalliy setTimeout () yoki setInterval () global funktsiyasini ikkita bilan almashtirish. mahalliy bo'lmagan Function.prototype.call usuli orqali chaqiruvni faollashtiradiganlar. Quyidagi misol mumkin bo'lgan almashtirishni ko'rsatadi:

// "bu" ob'ektining JavaScript taymerlari orqali o'tishini yoqish var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = funktsiyasi (vCallback, nDelay / *, argumentToPass1, argumentToPass2, va hokazo * /) (var oThis = this, aArgs = Array.prototype.slice.call (argumentlar, 2); __nativeST __ (funktsiyani vCallback misoli? function () (vCallback.apply (oThis, aArgs);): vCallback, nDelay);); window.setInterval = funktsiyasi (vCallback, nDelay / *, argumentToPass1, argumentToPass2 va boshqalar * /) (var oThis = this, aArgs = Array.prototype.slice.call (argumentlar, 2); __nativeSI __ (funktsiyani vCallback misoli? function () (vCallback.apply (oThis, aArgs);): vCallback, nDelay););

Bu ikkita almashtirish, shuningdek, IE -da taymerlarning qayta qo'ng'iroq qilish funktsiyalariga ixtiyoriy argumentlarning HTML5 standart o'tishiga imkon beradi. Shunday qilib, ular sifatida ishlatilishi mumkin standartga mos kelmaydigan polifillalar ham. A ga qarang standartga mos ko'p to'ldirish.

Yangi xususiyatlar testi:

MyArray = ["nol", "bir", "ikki"]; myArray.myMethod = funktsiyasi (sProperty) (ogohlantirish (argumentlar.length> 0? bu: bu);); setTimeout (ogohlantirish, 1500, "Salom dunyo!"); // setTimeout va setInterval -dan standart foydalanish saqlanib qolgan, lekin ... setTimeout.call (myArray, myArray.myMethod, 2000); // 2 soniyadan keyin setTimeout.call "nol, bir, ikki" ni bosib chiqaradi (myArray, myArray.myMethod, 2500, 2); // 2,5 soniyadan keyin "ikkita" ni bosib chiqaradi

Uning yanada murakkab, ammo modulli versiyasi uchun ( Daemon) JavaScript Daemons Management -ga qarang. Bu yanada murakkab versiya - bu usullarning katta va miqyosli to'plamidan boshqa narsa emas Daemon konstruktor. Biroq, Daemon konstruktorning o'zi klondan boshqa narsa emas MiniDaemon uchun qo'shimcha qo'llab -quvvatlash bilan boshlang'ich va boshida funksiyasini ishga tushirish paytida e'lon qilish mumkin jin . Shunday qilib MiniDaemon Framework oddiy animatsiyalar uchun tavsiya etilgan usul bo'lib qolmoqda, chunki Daemon usullar to'plamisiz, uning klonidir.

minidaemon.js

/ * \ | * | | * | :: MiniDaemon :: | * | | * | Tuzatish # 2 - 26 sentyabr, 2014.setInterval | * | https: // sayt / Foydalanuvchi: fusionchess | * | https://github.com/madmurphy/minidaemon.js | * | | * | Bu ramka GNU Lesser General Public License 3 -versiya yoki undan keyingi versiyasi ostida chiqariladi. | * | http://www.gnu.org/licenses/lgpl-3.0.html | * | \ * / funktsiyasi MiniDaemon (oOwner, fTask, nRate, nLen) (if (! (this && this instanceof MiniDaemon)) (return;) if (argument.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 = Cheksizlik; / * Bu xususiyatlar faqat o'qish uchun bo'lishi kerak * / MiniDaemon.prototype.SESSION = -1; MiniDaemon.prototype.INDEX = 0; MiniDaemon.prototype.PAUSED = rost; MiniDaemon.prototype.BACKW = to'g'ri; / * Global usullar * / MiniDaemon.forceCall = funktsiyasi (oDmn) (oDmn.INDEX + = oDmn.BACKW? -1: 1; agar .BACKW) === yolg'on || oDmn.isAtEnd ()) (oDmn.pause (); false qaytish;) rost qaytarish;); / * Misol usullari * / MiniDaemon.prototype.isAtEnd = function () (buni qaytaring. BACKW? IsFinite (this.length) && this.INDEX< 1: this.INDEX + 1 >this.length; ); MiniDaemon.prototype.synchronize = function () (if (this.PAUSED) (return;) clearInterval (this.SESSION); this.SESSION = setInterval (MiniDaemon.forceCall, this.rate, this);); MiniDaemon.prototype.pause = function () (clearInterval (this.SESSION); this.PAUSED = true;); MiniDaemon.prototype.start = funktsiyasi (bReverse) (var bBackw = Boolean (bReverse); if (this.BACKW === bBackw && (this.isAtEnd () ||! This.PAUSED)) (return;) this.BACKW = bBackw; this.PAUSED = false; this.synchronize (););

MiniDaemon argumentlarni qayta qo'ng'iroq qilish funktsiyasiga o'tkazadi. Agar siz bu xususiyatni qo'llab -quvvatlamaydigan brauzerlar bilan ishlashni xohlasangiz, yuqorida taklif qilingan usullardan birini ishlating.

Sintaksis

var myDaemon = yangi MiniDaemon ( thisObject, qayta qo'ng'iroq qilish[ , baho [, uzunlik]]);

Tavsif

Foydalanish eslatmalari

SetInterval () funktsiyasi odatda animatsiyalar kabi qayta -qayta bajariladigan funktsiyalar uchun kechikishni o'rnatish uchun ishlatiladi. WindowOrWorkerGlobalScope.clearInterval () yordamida intervalni bekor qilishingiz mumkin.

Agar siz o'z funktsiyangizni chaqirishni xohlasangiz bir marta belgilangan kechiktirilgandan keyin foydalaning.

Kechiktirish cheklovlari

Intervallarni joylashtirish mumkin; ya'ni setInterval () uchun qayta qo'ng'iroq, o'z navbatida, setInterval () ga qo'ng'iroq qilib, birinchisi hali ham davom etayotgan bo'lsa -da, boshqa intervalli ishini boshlashi mumkin. Buning ta'sirini kamaytirish uchun. Ishlash, intervallar besh darajadan oshib ketganda, brauzer avtomatik ravishda interval uchun 4 ms minimal qiymatni o'rnatadi. setInterval () ga chuqur joylashtirilgan qo'ng'iroqlarda 4 ms dan kam qiymat ko'rsatishga urinishlar 4 ms ga mahkamlanadi.

Brauzerlar, ba'zi hollarda, interval uchun yanada qattiqroq minimal qiymatlarni kiritishi mumkin, lekin bu odatiy bo'lmasligi kerak. Shuni ham yodda tutingki, qayta qo'ng'iroq qilish o'rtasida o'tkaziladigan vaqt, kechiktirilgan vaqtdan ko'proq bo'lishi mumkin; Misollar uchun WindowOrWorkerGlobalScope.setTimeout () da ko'rsatilganidan ko'proq kechikish sabablarini ko'ring.

Ishlash davomiyligi intervalli chastotadan qisqa ekanligiga ishonch hosil qiling

Agar sizning mantiqingiz vaqt oralig'idan ko'ra ko'proq vaqt talab qilishi mumkin bo'lsa, setTimeout () yordamida nomlangan funktsiyani rekursiv ravishda chaqirish tavsiya etiladi. Masalan, har 5 soniyada masofaviy serverni so'rov qilish uchun setInterval () dan foydalanilsa, tarmoqning kechikishi, javob bermaydigan server va boshqa ko'plab muammolar so'rovning belgilangan vaqtda bajarilishiga to'sqinlik qilishi mumkin. Shunday qilib, siz o'z navbatida navbat bilan qaytmaydigan XHR so'rovlariga duch kelishingiz mumkin.

  • Kimdan:
  • Ro'yxatga olingan: 2014.07.08
  • Xabarlar: 3,896
  • Yoqdi: 497

Mavzu: SetTimeOut va SetInterval, qaysi birini JavaScript -da ishlatish yaxshiroq?

Kodni bir necha marta muntazam ravishda ishga tushirish uchun funksiyadan foydalaning setInterval... Biroq, u bir qator kamchiliklarga ega, asosan turli brauzerlarda har xil xatti -harakatlar.

Birinchi farq - taymer keyingi ishga tushirish vaqtidagi farq. Keling, kichik testni yarataylik: biz oldingi yugurish boshidan va uning oxirigacha o'tgan vaqtni o'lchaymiz.

var d1 = yangi sana (), d2 = yangi sana (); setInterval (function () (var d = new Date (); document.body.innerHTML + = (d - d1) + "" + (d - d2) + "
"; // d1 = yangi sana () funktsiyasining boshiga belgi qo'ying; while (yangi sana () - d1< 200); // ничего не делаем 200 миллисекунд // И в конце функции d2 = new Date(); }, 1000);

Chiqish ikkinchi qatordan boshlab ma'lumotli bo'ladi.

Firefox, Opera, Safari va Chrome -da vaziyat xuddi shunday bo'ladi: birinchi raqam taxminan 1000 ga teng bo'ladi, ikkinchisi - 200 ga kam. Faqat farq qiymatlar oralig'ida bo'ladi. Chrome va Opera -ning eng kichik o'zgarishi.

2 Tomonidan javob berish PunBB (tahrir PunBB 2017.06.08 16:45)

  • Kimdan: Moskva, Sovxoznay 3, kv. 98
  • Ro'yxatga olingan: 2014.07.08
  • Xabarlar: 3,896
  • Yoqdi: 497

Yana sezilmaydigan va ko'paytirish qiyin bo'lgan, lekin ba'zida ko'p muammolarni keltirib chiqaradigan yana bir farq - bu tizim vaqtidagi o'zgarishlarga qarshilik. Agar siz keyingi testni o'tkazsangiz

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

Ishga tushgandan so'ng, tizim vaqtini bir daqiqaga orqaga surib qo'ying, keyin Firefox va Safari brauzerlarida raqamlarning o'zgarishi pauza qilinadi va bir daqiqadan so'ng yana boshlanadi. Albatta, tizim vaqtini qo'lda tarjima qilish juda kam uchraydigan holat, lekin ko'p tizimlarda Internetdagi serverlar bilan avtomatik sinxronizatsiya mavjud, shuning uchun ba'zi holatlarda bu omilni e'tiborsiz qoldirib bo'lmaydi.

SetInterval funktsiyasining yana bir kichik kamchiligi shundaki, uning harakatini to'xtatish uchun siz uning identifikatorini biror joyda eslab qolishingiz kerak, bu har doim ham qulay emas.

3 Tomonidan javob berish PunBB

  • Kimdan: Moskva, Sovxoznay 3, kv. 98
  • Ro'yxatga olingan: 2014.07.08
  • Xabarlar: 3,896
  • Yoqdi: 497

Re: SetTimeOut va SetInterval, qaysi birini JavaScript -da ishlatish yaxshiroq?

SetInterval -ning sanab o'tilgan kamchiliklaridan xalos bo'lish uchun siz bir nechta setTimeout -dan foydalanishingiz mumkin.

SetInterval -ga muhim alternativ - bu rekursiv setTimeout:

/ ** o'rniga: var timerId = setInterval (function () (alert ("tick");), 2000); * / var timerId = setTimeout (funktsiya belgisi () (ogohlantirish ("belgi"); timerId = setTimeout (belgi, 2000);), 2000);

Yuqoridagi kodda keyingi ijro avvalgisi tugagandan so'ng darhol rejalashtirilgan.

Recursive setTimeout - bu setIntervalga qaraganda ancha moslashuvchan vaqt usuli, chunki keyingi bajarilish vaqtini joriy natijalarga qarab boshqacha rejalashtirish mumkin.

Masalan, bizda har 5 soniyada serverdan yangi ma'lumotlar so'raladigan xizmat bor. Agar server haddan tashqari yuklangan bo'lsa, siz ovoz berish oralig'ini 10, 20, 60 soniyagacha oshirishingiz mumkin ... Va keyin hamma narsa normallashganda uni qaytaring.

Agar bizda muntazam ravishda protsessorni yuklaydigan vazifalar bo'lsa, biz ularning bajarilishiga sarflangan vaqtni taxmin qilishimiz va ertami -kechmi keyingi ishga tushirishni rejalashtirishimiz mumkin.

4 Tomonidan javob berish PunBB

  • Kimdan: Moskva, Sovxoznay 3, kv. 98
  • Ro'yxatga olingan: 2014.07.08
  • Xabarlar: 3,896
  • Yoqdi: 497

Re: SetTimeOut va SetInterval, qaysi birini JavaScript -da ishlatish yaxshiroq?

Recursive setTimeout qo'ng'iroqlar orasidagi pauzani kafolatlaydi, setInterval esa unday emas.

Keling, ikkita kodni taqqoslaylik. Birinchisi setInterval dan foydalanadi:

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

Ikkinchisi rekursiv setTimeout -dan foydalanadi:

var i = 1; setTimeout (funktsiya run () (func (i); setTimeout (ishga tushirish, 100);), 100);

SetInterval bilan ichki taymer har 100msda aniq yonadi va func (i) ni chaqiradi:

SetInterval bilan func qo'ng'iroqlari orasidagi haqiqiy pauza kodda ko'rsatilganidan kamroq!

Bu tabiiy, chunki funktsiyaning ishlash vaqti hech qanday hisobga olinmaydi, u intervalning bir qismini "yeydi".

Bundan tashqari, func biz kutganimizdan ko'ra murakkabroq bo'lishi mumkin va uni bajarish uchun 100 ms dan ko'proq vaqt kerak bo'lgan.

Bunday holda, tarjimon funktsiya tugashini kutadi, keyin taymerni tekshiradi va agar setIntervalga qo'ng'iroq qilish vaqti allaqachon o'tgan (yoki o'tgan) bo'lsa, keyingi qo'ng'iroq darhol sodir bo'ladi.

Agar funktsiya setInterval pauzasidan ko'proq vaqt talab qilsa, qo'ng'iroqlar hech qanday uzilishlarsiz amalga oshadi.

5 Tomonidan javob berish semay

  • Kimdan: Quddus
  • Ro'yxatga olingan: 2015.06.02
  • Xabarlar: 958
  • Yoqdi: 274

Re: SetTimeOut va SetInterval, qaysi birini JavaScript -da ishlatish yaxshiroq?

Bularning barchasi bajariladigan vazifaga bog'liq. Dastlab, SetTimeOut taymerni bir marta, SetInterval esa tsiklni ishga tushirish uchun ishlatiladi. Ammo ikkala funktsiyani ham skriptlarni aylantirish uchun ishlatish mumkin, masalan, SetTimeOut funktsiyasida rekursiv ravishda ishlasa, u amaliy tarzda SetIntervalga o'xshab ishlaydi.

Hozirgi vaqtda SetInterval -ning kamchiliklari shundaki, u skriptning (funksiyaning) bajarilish vaqtini hisobga olmaydi va agar siz, masalan, uni og'ir so'rovlar uchun ishlatsangiz, interval vaqti sezilarli darajada kamayadi va turli xil brauzerlarda farq qilishi mumkin.

Ammo yana takrorlayman, agar funktsiya yoki so'rov minimallashtirilsa, oxirgi foydalanuvchi farqni sezishi dargumon.
Shuning uchun, nima ishlatishni har kim o'zi hal qiladi.

Manba: http://learn.javascript.ru/settimeout-setinterval

Deyarli barcha JavaScript -ni dasturlari ma'lum vaqtdan keyin funktsional qo'ng'iroqni rejalashtirishga imkon beradigan ichki rejalashtirish taymeriga ega.

Xususan, bu xususiyat brauzerlarda va Node.JS serverida qo'llab -quvvatlanadi.

setTimeout

Sintaksis:

var timerId = setTimeout (func / code, delay [, arg1, arg2 ...])

Variantlar:

  • func / kod
    • Amalga oshiriladigan funktsiya yoki kod qatori.
    • String moslik uchun qo'llab -quvvatlanadi va eskirgan.
  • kechikish
    • Milisaniyadagi kechikish, 1000 millisekund 1 soniyaga teng.
  • arg1, arg2 ...
    • Funktsiyaga o'tish uchun argumentlar. IE9-da qo'llab-quvvatlanmaydi.
    • Funktsiya kechikish parametrida ko'rsatilgan vaqtdan keyin bajariladi.

Masalan, quyidagi kod bir soniyadan so'ng ogohlantirish ("Salom") ni chaqiradi:

funktsiyasi func ()(ogohlantirish ("Salom");) setTimeout (func, 1000);

Agar birinchi argument satr bo'lsa, tarjimon bu satrdan anonim funktsiyani yaratadi.

Ya'ni, bunday yozuv xuddi shunday ishlaydi:

SetTimeout ("ogohlantirish (" Salom ")", 1000);

Buning o'rniga anonim funktsiyalarni ishlating:

SetTimeout ( funktsiya ()(ogohlantirish ("Salom")), 1000);

Funktsiya parametrlari va kontekst

Barcha zamonaviy brauzerlarda, IE10 inobatga olingan holda, setTimeout funksiya parametrlarini belgilashga imkon beradi.

Quyidagi misolda IE9- dan tashqari hamma joyda "Salom, men Vasya" ko'rsatiladi.

SayHi funktsiyasi (kim)(ogohlantirish ("Salom, men" + kim);) setTimeout (sayHi, 1000, "Vasya");

... Biroq, aksariyat hollarda biz eski IEni qo'llab -quvvatlashga muhtojmiz va bu sizga dalillarni ko'rsatishga imkon bermaydi. Shuning uchun, ularni o'tkazish uchun qo'ng'iroq anonim funktsiyaga o'raladi:

SayHi funktsiyasi (kim)(ogohlantirish ("Salom, men" + kim);) setTimeout ( funktsiya ()(SayHi ("Vasya")), 1000);

SetTimeout orqali qo'ng'iroq qilish bu kontekstdan o'tmaydi.

Xususan, ob'ekt usulini setTimeout orqali chaqirish global kontekstda ishlaydi. Bu noto'g'ri natijalarga olib kelishi mumkin.

Masalan, user.sayHi () ga bir soniyadan so'ng qo'ng'iroq qilaylik:

Foydalanuvchi funktsiyasi (id) funktsiya ()(ogohlantirish (bu .id);); ) var user = yangi foydalanuvchi (12345); setTimeout (user.sayHi, 1000); // kutilgan 12345, lekin "aniqlanmagan" ni chop etadi

SetTimeout user.sayHi funktsiyasini global kontekstda ishga tushirgani uchun, bu orqali ob'ektga kira olmaydi.

Boshqacha qilib aytganda, setTimeout -ga bu ikkita qo'ng'iroq xuddi shunday qiladi:

// (1) bitta satr setTimeout (user.sayHi, 1000); // (2) bir xil narsa ikki qatorda var func = user.sayHi; setTimeout (funktsiya, 1000);

Yaxshiyamki, bu muammo oraliq funktsiyani yaratish orqali ham osonlikcha hal qilinadi:

Foydalanuvchi funktsiyasi (id)(bu .id = id; bu .sayHi = funktsiya ()(ogohlantirish (bu .id);); ) var user = yangi foydalanuvchi (12345); setTimeout ( funktsiya ()(user.sayHi ();), 1000);

Sarish funktsiyasi brauzer orqali o'tish argumentlari va ijro kontekstini saqlash uchun ishlatiladi.

Ijro etishni bekor qilish

SetTimeout funktsiyasi harakatni bekor qilish uchun ishlatilishi mumkin bo'lgan timerId -ni qaytaradi.

Sintaksis:

ClearTimeout (timerId)

Quyidagi misolda biz tanaffusni belgilaymiz va keyin o'chirib tashlaymiz (fikrimizni o'zgartiring). Natijada hech narsa bo'lmaydi.

var timerId = setTimeout ( funktsiya ()(ogohlantirish (1)), 1000); clearTimeout (timerId);

setInterval

SetInterval usuli setTimeout -ga o'xshash sintaksisga ega.

var timerId = setInterval (funktsiya / kod, kechiktirish [, arg1, arg2 ...])

Dalillarning ma'nosi bir xil. Ammo, setTimeout -dan farqli o'laroq, u funktsiyani bajarishni bir marta emas, balki uni belgilangan vaqt oralig'ida muntazam ravishda takrorlaydi. Siz qo'ng'iroq qilib, ijro etishni to'xtatishingiz mumkin:

ClearInterval (timerId)

Quyidagi misol, ishga tushganda, siz to'xtatish tugmachasini bosmaguningizcha har ikki soniyada bir xabarni ko'rsatadi:

<kirish turi = "tugmasi" onclick = "clearInterval (taymer)" qiymati = "(! LANG: To'xtatish" > !} <skript> var i = 1; var taymer = setInterval ( funktsiya ()(ogohlantirish (i ++)), 2000);skript>

SetInterval -da qo'ng'iroqlarni navbatga qo'yish va joylashtirish

SetInterval (funktsiya, kechikish) ni chaqirish funktsiyani belgilangan vaqt oralig'idan keyin bajarilishini belgilaydi. Ammo bu erda bir noziklik bor.

Aslida, qo'ng'iroqlar orasidagi pauza belgilangan vaqtdan kamroq.

Masalan, setInterval (function () (func (i ++)), 100) ni olaylik. Har 100msda funktsiyani bajaradi va har safar hisoblagichni oshiradi.

Quyidagi rasmda qizil blok - funcning bajarilish vaqti. Bloklar orasidagi vaqt - bu funksiyaning ishga tushishi orasidagi vaqt va u belgilangan kechikishdan kam!

Ya'ni, brauzer funktsiyani bajarilish vaqtini hisobga olmagan holda, funksiyani har 100 soniyada aniq ishga tushirishni boshlaydi.

Shunday bo'ladiki, funktsiyani bajarish kechiktirishdan ko'ra ko'proq vaqtni oladi. Masalan, funksiya murakkab va kechikish vaqti kichik. Yoki funktsiyani bajaruvchi ipni bloklaydigan ogohlantirish / tasdiqlash / tezlik iboralari mavjud. Bunday holda, qiziqarli narsalar boshlanadi.

Agar brauzer band bo'lganligi uchun funktsiyani ishga tushirish mumkin bo'lmasa, u navbatga qo'yiladi va brauzer bo'shab qolishi bilan bajariladi.

Quyidagi rasmda uzoq vaqt davom etadigan funktsiyaga nima bo'layotgani ko'rsatilgan.

SetInterval tomonidan boshlangan funktsiya chaqiruvi navbatga qo'shiladi va imkon bo'lganda darhol sodir bo'ladi:

Funktsiyaning ikkinchi bajarilishi birinchi tugagandan so'ng darhol sodir bo'ladi:

Ijro bir necha marotaba navbatga qo'yilmaydi.

Agar funktsiyani bajarish bir necha rejalashtirilgan bajarilishlardan ko'ra ko'proq vaqtni talab qilsa, u baribir navbatda turadi. Shunday qilib, uchirishlarning "to'planishi" yo'q.

Quyidagi rasmda setInterval funktsiyani 200ms ichida bajarishga harakat qiladi va qo'ng'iroqni o'chiradi. 300ms va 400ms da taymer yana uyg'onadi, lekin hech narsa o'tmaydi.

SetInterval (funktsiya, kechikish) ni chaqirish qatllar orasidagi haqiqiy kechikishni kafolatlamaydi.

Haqiqiy kechikish belgilanganidan katta yoki kamroq bo'lgan paytlar bor. Umuman olganda, hech bo'lmaganda kechikish bo'lishi haqiqat emas.

Ichki o'rnatilgan setTimeout takrorlanishi

Nafaqat muntazam takrorlash, balki ishga tushirish o'rtasida kechikish talab qilinadigan hollarda, funktsiya har safar bajarilganda setTimeout qayta tiklanadi.

Quyida ular orasidagi 2 soniyali interval bilan ogohlantirish beruvchi misol keltirilgan.

<kirish turi = "tugmasi" onclick = "clearTimeout (taymer)" qiymati = "(! LANG: To'xtatish" > !} <skript> var i = 1; var taymer = setTimeout ( Run funktsiyasi ()(ogohlantirish (i ++); taymer = setTimeout (ishga tushirish, 2000);), 2000);skript>

Ijro vaqt jadvalida ishlash o'rtasida aniq kechikishlar bo'ladi. 100ms kechikish uchun rasm:

Taymerning minimal kechikishi

Brauzer taymeri eng past kechikish vaqtiga ega. Zamonaviy brauzerlarda u noldan 4 ms gacha o'zgarib turadi. Keksa odamlarda u balandroq bo'lishi va 15 m ga etishi mumkin.

Standartga ko'ra, minimal kechikish 4 ms. Shunday qilib, setTimeout (.., 1) va setTimeout (.., 4) o'rtasida hech qanday farq yo'q.

Nolinchi kechikishdagi setTimeout va setInterval xatti-harakatlari brauzerga xosdir.

  1. Operada setTimeout (.., 0) setTimeout bilan bir xil (.., 4). Bu setTimeout (.., 2) ga qaraganda kamroq ishlaydi. Bu brauzerning o'ziga xos xususiyati.
  2. Internet Explorer -da nolinchi kechikish setInterval (.., 0) ishlamaydi. Bu, ayniqsa setInterval uchun amal qiladi, ya'ni. setTimeout (.., 0) yaxshi ishlaydi.

Haqiqiy javob chastotasi

Triggering juda kam uchraydi, ba'zi hollarda kechikish 4ms emas, balki 30ms yoki hatto 1000ms bo'lishi mumkin.

Ko'pgina brauzerlar (birinchi navbatda ish stoli), agar tab faol bo'lmasa ham, setTimeout / setInterval -ni bajarishda davom etadi. Shu bilan birga, ularning ko'pchiligi (Chrome, FF, IE10) minimal taymer chastotasini sekundiga 1 martagacha kamaytiradi. Ma'lum bo'lishicha, taymer "fon" ko'rinishida ishga tushiriladi, lekin kamdan -kam hollarda.

Batareya quvvati bilan ishlaganda, noutbukda - brauzerlar kodni kamroq bajarish va batareya quvvatini tejash uchun chastotani kamaytirishi mumkin. IE bu bilan ayniqsa mashhur. Sozlamalarga qarab, kamaytirish bir necha barobargacha bo'lishi mumkin. Agar protsessor yuki juda og'ir bo'lsa, JavaScript taymerlarni o'z vaqtida qayta ishlamasligi mumkin. Bu ba'zi setInterval ishlarini o'tkazib yuboradi.

Xulosa: siz 4ms chastotasini boshqarishingiz kerak, lekin bunga ishonmasligingiz kerak.

Intervallarni konsolga chiqarish Qo'ng'iroqlar orasidagi intervallarni hisoblaydigan kod shunday ko'rinadi:

var timeMark = yangi sana; setTimeout ( go () funktsiyasi(var diff = new Date - timeMark; // sahifa o'rniga konsolga boshqa kechikishni chop eting konsol .log (farq); // oxirini eslang, // qo'ng'iroqlar orasidagi kechikishni aniq o'lchash uchun timeMark = yangi sana; setTimeout (borish, 100); ), 100);

SetTimeout (func, 0) hiylasi

Bu hiyla JavaScript xakerlik yilnomalariga kirishga loyiqdir.

Agar siz uni joriy skript tugagandan keyin ishlatmoqchi bo'lsangiz, funktsiya setTimeout (func, 0) bilan o'ralgan.

Gap shundaki, setTimeout hech qachon funktsiyani darhol bajarmaydi. U faqat uning amalga oshirilishini rejalashtiradi. Ammo JavaScript tarjimoni rejalashtirilgan funktsiyalarni bajarishni faqat joriy skript bajarilgandan keyingina boshlaydi.

Standartga ko'ra, setTimeout hech bo'lmaganda 0 kechiktirilgan funktsiyani bajara olmaydi.Biz oldin aytganimizdek, odatda kechikish 4 ms bo'ladi. Ammo bu erda asosiy narsa shundaki, ijro har qanday holatda ham joriy kod bajarilgandan keyin bo'ladi.

Masalan:

var natija; showResult funktsiyasi ()(ogohlantirish (natija);) setTimeout (showResult, 0); natija = 2 * 2; // chop etadi 4

Jami

SetInterval (func, delay) va setTimeout (func, delay) usullari funcni millisekunddan keyin muntazam / bir marta ishga tushirishga imkon beradi.

Ikkala usul ham taymer identifikatorini qaytaradi. ClearInterval / clearTimeout -ni chaqirib, bajarishni to'xtatish uchun ishlatiladi.

| | setInterval | setTimeout | || ----------- | ---------- | | Vaqt | Qo'ng'iroq taymerda davom etmoqda. Agar tarjimon band bo'lsa, navbatga bitta qo'ng'iroq kiradi. Funktsiyaning bajarilish vaqti hisobga olinmaydi, shuning uchun bir yugurish oxiridan boshqasining boshigacha bo'lgan vaqt oralig'i boshqacha bo'lishi mumkin. | SetInterval o'rniga setTimeout -ga rekursiv qo'ng'iroq ishlatiladi, bu erda qatllar o'rtasida qat'iy pauza kerak. | | Kechikish | Minimal kechikish: 4 ms. | Minimal kechikish: 4 ms. | | Brauzer xususiyatlari | IEda kechikish 0 ishlamaydi | Opera-da nol kechikish 4 ms ga teng, boshqa kechikishlar aniq bajariladi, shu jumladan nostandart 1ms, 2ms va 3ms. |

Skript tillarida dasturlashda vaqti -vaqti bilan pauza yaratish kerak - dasturning bajarilishini bir muddat to'xtatib, keyin ishlashni davom ettirish. Masalan, VBS va PHP skriptlarida quyidagi usullar mumkin:

VBS: wscript.sleep 1500 (1,5 soniya to'xtating)

PHP: uyqu (10); (10 soniya to'xtab turing)

Bunday pauzalarda ish vaqti tizimi (PHP yoki VBS) hech narsa qilmay... Javascriptda shunga o'xshash narsani intuitiv ravishda ishlatishga harakat qilayotgan dastur yoqimsiz ajablanib qoladi. Javascript -da pauza yaratishga urinishda odatdagi xato quyidagicha ko'rinadi:

Badtest () funktsiyasi (uchun (var i = 1; i< 10; i++) { window.setTimeout("document.getElementById("test1").value += " + i, 900) } }

Sizningcha, pastadirdan o'tayotganda, keyingi raqamni chizish, sizning setTimeout Javascript ishini halol to'xtatadi, 0,9 soniya kutadi, kerakli maydonni kiritish maydonining oxiriga qo'shadi va keyin ishlashni davom ettiradi. Lekin aslida unday emas: setInterval va setTimeout Javascriptda faqat qavs ichida ko'rsatilgan amal (yoki funksiya) kechiktiriladi. Bizning misolimizda quyidagilar ro'y beradi.

  1. i = 1;
  2. kirish maydoniga "1" raqamini qo'shishni 0,9 soniyaga qoldiring;
  3. darhol bu muammoni qo'ygandan so'ng, tsikl davom etadi: i = 2;
  4. kirish maydoniga "2" raqamini qo'shishni 0,9 soniyaga kechiktiring;

Darhol masalan, 1 milodiy (ya'ni, 900 msga nisbatan, kichik) degan ma'noni anglatadi: tsikl o'z ishini deyarli bir zumda bajaradi va shu vaqtning o'zida bir nechta kutilayotgan vazifalarni yaratadi. Bu shuni anglatadiki, "chizish" kutayotgan barcha vazifalar deyarli bir vaqtning o'zida, yangi raqamlarni qo'shish o'rtasida pauza qilmasdan bajariladi. Tsikl boshlanadi; hamma narsa 0,9 soniya davomida muzlaydi; va shirrr - barcha raqamlar ketma -ket ketma -ket o'qqa tutiladi.

Va bu holda, qanday qilib to'g'ri qo'llash kerak setTimeout? Bu qiyin. Funktsiyani chaqirish kerak rekursiv ravishda(funktsiya ichidan, xuddi shu funktsiya) va bu jarayon cheksiz bo'lmasligi uchun to'xtash shartini o'rnating (masalan, bosilgan raqamning qiymati):

Welltest () funktsiyasi (agar (i< 9) { document.getElementById("test2").value += ++i window.setTimeout("welltest()", 400) } }

Va yana bir o'zgaruvchi i funktsiyadan tashqarida ishga tushirilishi kerak, masalan:

Endi hamma narsa kerak bo'lganda ishlaydi (biz kechikish vaqtini 0,9 s dan 0,4 s gacha kamaytirdik). Ammo bunday vazifalar uchun ishlatmaslik mantiqan to'g'ri keladi setTimeout a setInterval(garchi bu ikkita funktsiyani talab qilsa):

Besttest () (window.i = 0 window.timer1 = window.setInterval ("draw ()", 400)) funksiya draw () (document.getElementById ("test3"). Qiymat + = ++ i if (i) > = 9) clearInterval (window.timer1))

Javascirpt usulining xususiyati setInterval"o'z -o'zidan" o'tmasligi, uni maxsus usul bilan to'xtatish kerak aniq Interval... Nimani to'xtatish kerakligini tushuntirish uchun, kechiktirilgan harakat vazifasiga maxsus identifikator - taymer beriladi: window.timer1 = window.setInterval (...).

Identifikatorlar usul yordamida yaratilgan vazifalarga ham berilishi mumkin setTimeout... Barcha taymer identifikatorlari bir -biridan farq qilishi kerak (joriy brauzer oynasida yagona). Keyin siz kechiktirilgan amallarni ishlatadigan oynada bir nechta vazifalarni yaratishingiz mumkin va bu vazifalar parallel ravishda bajariladi (masalan, agar kompyuterda resurslar etarli bo'lsa), bu PHP yoki VBSda umuman mumkin emas.

Bu erda bir vaqtning o'zida bir nechta Javascript taymerlari ishlaydigan sahifaning namunasi: setinterval.htm (setinterval.js faylida Javascript funktsiyalari). Barcha sahifa taymerlarining ishlashi (menyudan tashqari) Esc tugmachasini bosib to'xtatilishi mumkin. Taymerlarning barcha misollari "tabiiy" ga asoslanadi (mavhum emas i ++) sanash - vaqt yoki masofa. Barcha "soatlar" maxsus desinxronizatsiya qilingan (aniqlik uchun). Masofadagi taymerlar "indikator" va ochiladigan (pastga) menyuda ishlatiladi.

Ochiladigan menyu

Bizning tortib olinadigan menyuimiz aslida ("sarlavha" ostidan) chiqariladi: elementlar qanday bo'shashini ko'rish uchun bo'shliqlar mavjud. Kutilmaganda, biz har xil uzunlikdagi ro'yxatlar uchun bir xil darajada silliq chiqa olmasligimiz ma'lum bo'ldi - bu, ehtimol, kompyuterning past ishlashi (AMD Athlon 999 MGts) tufayli.

Ko'rinib turibdiki, go'zallik va uyg'unlik uchun menyu elementlarining ro'yxati bir vaqtning o'zida chiqib ketishi kerak. Ya'ni, uzunroq ro'yxatlar tezroq, qisqaroqlari pastroq tezlikda chiqib ketishi kerak. Buni quyidagicha amalga oshirish mumkin ko'rinadi:

  1. Biz "ketish" ning umumiy vaqtini belgilaymiz, masalan, 200 ms.
  2. Agar ochiladigan ro'yxatning balandligi 20 piksel bo'lsa, biz uni bir pikselda 10 ms tezlik bilan pastga siljitishimiz mumkinligi aniq - keyin 200 msda butun ro'yxat ochiladi.
  3. Agar ochiladigan oynaning balandligi 40 piksel bo'lsa, bir vaqtning o'zida mos bo'lishi uchun biz uni 5 piksel ichida bir vaqtning o'zida bir piksel pastga siljitishimiz kerak.

Bu mantiqqa ko'ra, agar ochiladigan ro'yxat balandligi 200 piksel bo'lsa, biz uni bir pog'onada 1 milodiy ichida pastga siljitishimiz kerak. Ammo bu tezlik bizning kompyuterimizda ishlamaydi - brauzer ro'yxatning yangi o'rnini bir millisekundda chizishga ulgurmaydi. Ha. Javascriptda sanash uchun vaqt bor (nima sanash kerak?) Va brauzerda (Firefox) ko'rsatishga vaqti yo'q. Internet uchun odatiy holat.

Shunday qilib, menyudan chiqib ketish vaqtini ko'p jihatdan tayoqchalar yordamida tenglashtirish mumkin va bu tezroq kompyuterda qanday ishlashi hozircha noma'lum. Ammo biz eng sekiniga ishonishimiz kerak, to'g'rimi? Algoritm (kompyuter tezligini hisobga olmaganda) shunday bo'ladi:

  1. Biz ro'yxatning umumiy chiqish vaqtini o'rnatdik: vaqt = 224 (ms).
  2. Biz tsiklda bitta interval uchun minimal vaqtni o'rnatdik: kechikish = 3 (ms).
  3. Ro'yxatni ko'chirish uchun minimal qadamni o'rnating: ofset = 1 (px).
  4. Biz bularning barchasini ro'yxatning balandligiga qarab o'zgartiramiz: 1) kechikish (interval) vaqtini balandlikka teskari nisbatda va umumiy vaqtga to'g'ridan -to'g'ri mutanosib ravishda oshirish (224 balandlikda, koeffitsient 1); 2) agar balandlik 40 pikseldan oshsa, minimal qadamni balandlikka mutanosib ravishda oshiring. Eng sekin kompyuter uchun doimiy "40" empirik tarzda olinadi. Pentium 4 protsessorli 2.53 gigagertsli kompyuterda o'tkazilgan testlar aynan shu raqamni ko'rsatdi - 40. Aks holda, taymerlar yirtqich bo'lib ketadi, ro'yxatlar joyida emas.

Endi ro'yxatlar ozmi -ko'pmi tarqalmoqda. Ko'p yoki kamroq o'xshash vaqt uchun. Setinterval.htm sahifasida.

Mana, Bru-mo'ylov:

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

Menyudan ichki ro'yxatlarni olib keladigan funktsiyaning o'zi, ko'rib turganingizdek, juda oddiy. Buni faqat shu satr bilan ishlatish kifoya:

Ts.timer1 = setInterval (function () (slide_do (ts, maxtop, ofset)), kechikish)

Xo'sh, ishga tushirishdan oldin, bu maxtop va ofsetlarning barchasini hisoblang, shuningdek ro'yxatni mintop holatiga qo'ying. "Dastlabki" funktsiyasi nima qiladi slayd () 40 qatorli o'lchamlar. Va barchasi birgalikda - setinterval.js faylida. Ha, va bu axloqsizlik uslublar jadvalisiz ishlamaydi.