JavaScript kullanarak belirli bir gecikmeden sonra komut dosyası yürütme


189

Herhangi bir JavaScript yöntem jQuery'ye benzer var delay()ya da wait()(belirli bir zaman miktarı için bir komut yürütme geciktirmek için)?

Yanıtlar:


189

Aşağıdakiler var:

setTimeout(function, milliseconds);

işlevin yürütüleceği süreden sonra iletilebilen işlev.

Bakınız: Pencere setTimeout()Yöntemi .


3
Yürütülen bir ifade değil, bir işlev. @Marius'un cevabı bunu gösteriyor.
pedrofurla

117
bu bir gecikme değil, bir çatal. Gecikme aynı iş parçacığında çalışmalıdır.
DragonLord

13
Bu hemen function_reference komutunu yürütür. "Çalışmak" için (eşzamansız olarak) şöyle belirtilmelidir: setTimeout (function () {MethodToCall ();}, 1000);
Bernoulli IT

6
JavaScript'ten bahsettiğimizi belirtmek istiyorum; "iş parçacıklarını" getirmek veya "eşzamanlı olarak" çalışması gerektiği teknik ve anlamsal olarak doğru olabilir, ancak bu yöntemlerden herhangi birinde bir gecikme elde etmenin hiçbir yolu olmadığını düşünerek JavaScript bağlamına gerçekten uymuyor (yapmazsınız) t Diğer dillerde yaptığınız gibi JS'de "thread" oluşturun). Ayrıca, function_referencesiz eklemezseniz bu hemen yürütülmez (). Yani function_referencesadece bu - bir referans; içeri aktarma function_reference()işlevi derhal çağırır.
Danny Bullis

237

Sadece herkesin söylediklerine eklemek için setTimeout: Gelecekte parametreyle bir işlevi çağırmak istiyorsanız, bazı anonim işlev çağrıları ayarlamanız gerekir.

Daha sonra çağrılabilmesi için işlevi bağımsız değişken olarak geçirmeniz gerekir. Aslında bu, adın arkasında parantez olmadan anlamına gelir. Aşağıdaki uyarıyı bir kerede arayacak ve 'Merhaba dünya' gösterecektir:

var a = "world";
setTimeout(alert("Hello " + a), 2000);

Bunu düzeltmek için bir fonksiyonun adını (Flubba'nın yaptığı gibi) koyabilir veya anonim bir fonksiyon kullanabilirsiniz. Bir parametre iletmeniz gerekiyorsa, anonim bir işlev kullanmanız gerekir.

var a = "world";
setTimeout(function(){alert("Hello " + a)}, 2000);
a = "Stack Overflow";

Ancak bu kodu çalıştırırsanız, 2 saniye sonra pop-up pencerenin 'Merhaba Yığın Taşması' diyeceğini göreceksiniz. Bunun nedeni, a değişkeninin değerinin bu iki saniyede değişmesidir. İki saniye sonra 'Merhaba dünya' demesini sağlamak için aşağıdaki kod snippet'ini kullanmanız gerekir:

function callback(a){
    return function(){
        alert("Hello " + a);
    }
}
var a = "world";
setTimeout(callback(a), 2000);
a = "Stack Overflow";

2 saniye bekleyip 'Merhaba dünya' açılır.


37

Sadece biraz genişletmek için ... Doğrudan setTimeoutçağrıda kod yürütebilirsiniz , ancak @patrick'in söylediği gibi, normalde böyle bir geri çağırma işlevi atarsınız. Zaman milisaniyedir

setTimeout(func, 4000);
function func() {
    alert('Do stuff here');
}

27

Gerçekten delay(ne olursa olsun) bir engelleme (senkron) işlevine sahip olmak istiyorsanız , neden böyle bir şey yapmıyorsunuz:

<script type="text/javascript">
    function delay(ms) {
        var cur_d = new Date();
        var cur_ticks = cur_d.getTime();
        var ms_passed = 0;
        while(ms_passed < ms) {
            var d = new Date();  // Possible memory leak?
            var ticks = d.getTime();
            ms_passed = ticks - cur_ticks;
            // d = null;  // Prevent memory leak?
        }
    }

    alert("2 sec delay")
    delay(2000);
    alert("done ... 500 ms delay")
    delay(500);
    alert("done");
</script>

2
Bu çözümün zorluğu, aktif olarak bir işlemci kullanmasıdır, bu da daha fazla güç kullanımı ve diğer iş parçacıkları / süreçler (örneğin diğer sekmeler, diğer programlar) için mevcut kaynaklarda bir azalmaya yol açar. Bunun aksine, uyku bir iş parçacığının sistem kaynaklarını kullanımını geçici olarak askıya alır.
ramcdougal

1
Date.now () yerine Date.now () kullanmak daha iyi ve bellek sızıntılarını düşünmeyin
WayFarer

1
Tabii ki CPU yoğun, ama hızlı ve kirli testler için işe yarıyor
Maris B.

Ben iş parçacığı delay( bu soruyu cevaplamak için ) ing önce yenilemek, böylece iş parçacığı kilitlemez bir sürümünü istiyorum . Bunu yapmanın bir yolu var mı?
Gui Imamura

3
Daha kompakt bir rutin: işlev gecikmesi (ms) {var start_time = Date.now (); while (Date.now () - başlangıç_ zamanı <ms); }
Duke

15

SetTimeout'u kullanmanız ve bir geri arama işlevi iletmeniz gerekir . Javascript'te uykuyu kullanamamanızın nedeni, bu arada tüm sayfanın herhangi bir şey yapmasını engellemenizdir. İyi bir plan değil. Javascript'in etkinlik modelini kullanın ve mutlu kalın. Kavga etme!


2
Yine de test amaçları için yararlı olacaktır. Yeni bir HTTP isteği yapılmadan önce sayfa değişikliklerini değerlendirmek için form gönderimini birkaç saniye geciktirmek gibi.
rushinge

1
@rushinge daha sonra formu göndermek ve varsayılan form gönderme özelliğini devre dışı bırakmak için geri aramayı ayarlayın
Populus

1
Kod olarak bir bağlantı bırakmak kötü bir fikir ... şimdi işe yaramadı.
Emmet,

1
Ya da biliyorsun, düzeltebilirim.
Patrick

14

Bazı kodları düzenli aralıklarla art arda çalıştırmak için window.setInterval () öğesini de kullanabilirsiniz .


2
setInterval () kullanılmamalı, bunun yerine setTimeout kullanmalı
paul

9
setTimeout()bir kez setInterval()yapar, tekrar tekrar yapar. Kodunuzun her 5 saniyede bir çalışmasını istiyorsanız,setInterval() , iş için yapılır.
rcoup

11

Önceki yorumları eklemek için aşağıdakileri söylemek istiyorum:

setTimeout()JavaScript işlevi kendi başına script yürütmeye ara ama sadece gelecekte kod Eninde yürütmek için derleyici söyler etmez.

JavaScript'te yerleşik olarak yürütmeyi duraklatabilecek bir işlev yoktur. Ancak, işlevi kullanarak Date()ve ihtiyacınız olan zaman aralığını ekleyerek, koşulsuz döngü gibi bir şeyi yapan zamana ulaşana kadar kendi işlevinizi yazabilirsiniz .


11

Yalnızca bir gecikmeyi test etmeniz gerekiyorsa bunu kullanabilirsiniz:

function delay(ms) {
   ms += new Date().getTime();
   while (new Date() < ms){}
}

Ve sonra 2 saniye geciktirmek istiyorsanız:

delay(2000);

Yine de üretim için en iyi olmayabilir. Yorumlarda daha fazlası


@ U2744 SNOWFLAKE Yorumunuzda biraz daha hassas olabilir misiniz?
Christoffer

1
Bu, dizüstü bilgisayarların ve diğer mobil cihazların pillerini tüketen ve muhtemelen UI'nin yanıt vermesini (hatta görüntülemesini) önleyecek yoğun bir döngü.
Ry-

@ U2744SNOWFLAKE Mantıklı. Bu işlevi ne için kullandığımın cevabını güncelledik :)
Christoffer

2
Hızlı ve kirli (ve geçici) bir çözüm için geliştirmede yeterince iyi çalışır.
HumanInDisguise

5

kodu neden bir vaadin arkasına koyamıyorsun? (başımın üst kısmına yazılmıştır)

new Promise(function(resolve, reject) {
  setTimeout(resolve, 2000);
}).then(function() {
  console.log('do whatever you wanted to hold off on');
});


5

Basit cevap:

setTimeout(
    function () {
        x = 1;
    }, 1000);

Yukarıdaki fonksiyon 1 saniye (1000 ms) bekler ve sonra x'i 1'e ayarlar. Açıkçası bu bir örnektir; anonim işlev içinde istediğiniz her şeyi yapabilirsiniz.


4

Arama için üç farklı yöntemle Maurius'un açıklamasını (en yüksek oylanan yanıt) gerçekten beğendim setTimeout.

Kodumda bir AJAX kaydetme olayı tamamlandıktan sonra otomatik olarak önceki sayfaya otomatik olarak gitmek istiyorum. Kaydetme etkinliğinin tamamlanması, CSS'de kaydetmenin başarılı olduğunu gösteren hafif bir animasyon içerir.

Kodumda ilk iki örnek arasında bir fark buldum:

setTimeout(window.history.back(), 3000);

Bu zaman aşımını beklemez - gecikme için hangi sayıya girersem vereyim neredeyse arka () hemen çağrılır.

Ancak bunu şu şekilde değiştirin:

setTimeout(function() {window.history.back()}, 3000);

Tam da umduğum şeyi yapıyor.

Bu, back () işlemine özgü değildir, aynı şey gerçekleşir alert(). Temel olarak alert()ilk durumda kullanılanlarla, gecikme süresi göz ardı edilir. Açılır pencereyi kapattığımda CSS için animasyon devam ediyor.

Bu nedenle, yerleşik işlevler kullanıyor ve bağımsız değişkenler kullanmasanız bile, açıkladığı ikinci veya üçüncü yöntemi öneririm.


1

Arada bir gecikmeyle çalıştırmak istediğim bazı ajax komutlarım vardı. İşte bunu yapmanın bir yolunun basit bir örneği. Alışılmadık yaklaşımım için parçalara ayrılmaya hazırım. :)

//  Show current seconds and milliseconds
//  (I know there are other ways, I was aiming for minimal code
//  and fixed width.)
function secs()
{
    var s = Date.now() + ""; s = s.substr(s.length - 5);
  return s.substr(0, 2) + "." + s.substr(2);
}

//  Log we're loading
console.log("Loading: " + secs());

//  Create a list of commands to execute
var cmds = 
[
    function() { console.log("A: " + secs()); },
    function() { console.log("B: " + secs()); },
    function() { console.log("C: " + secs()); },
    function() { console.log("D: " + secs()); },
    function() { console.log("E: " + secs()); },
  function() { console.log("done: " + secs()); }
];

//  Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)
{
    setTimeout(cmd, ms * i);
});

// Log we've loaded (probably logged before first command)
console.log("Loaded: " + secs());

Kod bloğunu kopyalayıp bir konsol penceresine yapıştırabilir ve şöyle bir şey görebilirsiniz:

Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076

1

Gecikme ile fonksiyonunuzu çağırmanın en basit çözümü:

function executeWithDelay(anotherFunction) {
    setTimeout(anotherFunction, delayInMilliseconds);
}

0

gecikme fonksiyonu:

/**
 * delay or pause for some time
 * @param {number} t - time (ms)
 * @return {Promise<*>}
 */
const delay = async t => new Promise(resolve => setTimeout(resolve, t));

asyncfonksiyon kullanımı :

await delay(1000);

-1

Diğerleri gibi, setTimeout sizin için en güvenli bahistir
Ancak bazen mantığı yeni bir işleve ayıramazsınız, sonra milisaniye almak ve gecikmeyi kendiniz yapmak için Date.now () kullanabilirsiniz ....

function delay(milisecondDelay) {
   milisecondDelay += Date.now();
   while(Date.now() < milisecondDelay){}
}

alert('Ill be back in 5 sec after you click OK....');
delay(5000);
alert('# Im back # date:' +new Date());

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.