Bir parametreyi setTimeout () geri aramasına nasıl iletebilirim?


825

Şuna benzeyen bazı JavaScript kodu var:

function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    var topicId = xmlhttp.responseText;
    setTimeout("postinsql(topicId)",4000);
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}

topicIdTanımlı olmayan bir hata alıyorum setTimeout()İşlevi kullanmadan önce her şey çalışıyordu .

Bir postinsql(topicId)süre sonra fonksiyonumun çağrılmasını istiyorum . Ne yapmalıyım?


75
Böyle eski bir konu hakkında biraz yorum yapmak acıyor ama sadece üçüncü bir versiyon sunmak zorundayım (ki bence çok daha temiz): setTimeout (postinsql.bind (null, topicId), 4000)
1'de Hobblin

14
@Hobblin: Rekoru düzeltmek neden acıyor? Bu popüler soruya inmek ve eski, reddedilmiş çağrı stilini görmek başkalarına daha fazla zarar vermez mi?
Dan Dascalescu


@dbliss Benim önerim zaten cevapların birçoğunda belirtilmiş ve burada bir cevap olarak eklenmiştir: stackoverflow.com/a/15620038/287130 Ama
önerimin

@Hobblin ah, bunu işaret ettiğiniz için çok teşekkürler. sizin tarafınızdan gönderilen bir cevap arıyor ve bunu kaçırmıştı.
dbliss

Yanıtlar:


1122
setTimeout(function() {
    postinsql(topicId);
}, 4000)

Anonim bir işlevi bir dize yerine parametre olarak beslemeniz gerekir, ikinci yöntem ECMAScript belirtimine göre çalışmamalıdır, ancak tarayıcılar sadece yumuşaktır. Bu uygun bir çözümdür, kullanırken bir dizeyi 'işlev' olarak geçirmeye asla güvenmeyin setTimeout()ya setInterval()da değerlendirilmesi gerekir ve doğru değildir.

GÜNCELLEME:

Hobblin'in soruya yaptığı yorumlarında söylediği gibi , artık setTimeout kullanarak işleve argümanlar iletebilirsiniz Function.prototype.bind().

Misal:

setTimeout(postinsql.bind(null, topicId), 4000);

30
window.setTimeoutbir DOM yöntemidir ve bu nedenle ECMAScript belirtimi tarafından tanımlanmaz. Bir dizeyi geçirmek her zaman tarayıcılarda çalışmıştır ve fiili bir standarttır - aslında, daha sonra JavaScript 1.2 ile bir işlev nesnesini geçirme yeteneği eklenmiştir - açıkça HTML5 taslak özelliğinin bir parçasıdır ( whatwg.org/specs/web -apps / current-work / multipage /… ). Bununla birlikte, bir işlev nesnesi yerine bir dize kullanmak genellikle zayıf stil olarak kabul edilir, çünkü aslında bir gecikme biçimidir eval().
Miles

2
var temp = setTimeout (function () {postinsql (topicId);}, 4000); clearTimeout (sıcaklık); ??
Josh Mc

12
TopicId zaman aşımı ayarlandıktan sonra ancak işlev çağrılmadan önce değişirse ne olur?
pilau

22
@pilau tam olarak benim sorunum: Anonim işlevde kullanılan değişkenler zaman aşımından önce değişiyorsa (örneğin bir for döngüsünde) o zaman işlev içinde de değişecektir. Yani benim örnekte bir for döngüsünde 5 farklı zaman aşımı ayarı aslında aynı değişkenleri kullanarak sona erdi. Bu cevabı kullanırken dikkatli olun!
Cristian

10
@pilau başka bir kapanış kullanarak topicId = 12 yardımcı olacaktır; işlev postinsql (topicId) {console.log (topicId); } işlev setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13;
Halis Yılboğa

727

Modern tarayıcılarda "setTimeout", zamanlayıcının sonunda dahili işleve parametre olarak gönderilen üçüncü bir parametre alır.

Misal:

var hello = "Hello World";
setTimeout(alert, 1000, hello);

Daha fazla detay:


56
Bu cevabın neden en iyi olarak seçilmediğinden emin değilim. Anonim bir işlev kullanmak elbette işe yarar, ancak orijinal bir setTimeout işlev çağrısına üçüncü bir parametre iletebiliyorsanız ... neden olmasın?
Kris Schouw

54
Çünkü hala çok vahşi IE sürümlerinde çalışmaz.
Aaron

4
Bu cevap aslında bir olay nesnesini geçebilmemi sağladı, diğer yöntemler ise olmadı. Anonim bir fonksiyonum vardı.
Glenn Plas

27
Çok daha iyi cevap. Parametrenizi "setTimeout" çağrısı ile anonim işlevin fiili yürütülmesi arasında değiştiren bir kodunuz varsa, anonim işlevi, setTimeout çağrısı sırasında olduğu gibi değiştirilmiş bir değer alır. örneğin: için (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } bu 100 kez "100" kaydeder (FF üzerinde test edilmiştir). Mevcut cevap bundan kaçınmaya yardımcı olur.
kök

1
Acording developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout Internet Explorer için geri arama argümanlar sadece IE8 birçok sitede olduğu gibi dikkatli olun, sürümleri> = 10 desteklenir ve IE9 hala bazı alakalı pay aldığı edilir.
le0diaz

154

Biraz araştırma ve test yaptıktan sonra tek doğru uygulama:

setTimeout(yourFunctionReference, 4000, param1, param2, paramN);

setTimeout tüm ekstra parametreleri fonksiyonunuza iletir, böylece orada işlenebilirler.

Anonim işlev çok temel şeyler için çalışabilir, ancak "this" i kullanmak zorunda olduğunuz bir nesne içinde çalışmasını sağlamanın bir yolu yoktur. Herhangi bir anonim işlev "this" i pencereye işaret edecek şekilde değiştirir, böylece nesne referansınızı kaybedersiniz.


24
Kalbimdeki üzüntü ile bilgilendirmeliyim: bu internet explorer'da çalışmıyor. : / Tüm ekstra parametreler tanımsız olarak gelir.
Amalgovinus

6
Sadece kullanıyorumvar that = this; setTimeout( function() { that.foo(); }, 1000);
Ed Williams

2
Bu doğrudur ve HTML5'te belirtilmiştir. whatwg.org/specs/web-apps/current-work/multipage/…
Garrett

4
Bu Fabio'nun cevabı ile tamamen aynı .
Dan Dascalescu

1
Acording developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout Internet Explorer için geri arama argümanlar sadece IE8 birçok sitede olduğu gibi dikkatli olun, sürümleri> = 10 desteklenir ve IE9 hala bazı alakalı pay aldığı edilir.
le0diaz

45

Bu zaten "doğru" bir cevabı olan çok eski bir soru ama burada kimsenin bahsetmediği başka bir yaklaşımdan söz edeceğimi düşündüm. Bu mükemmel alt çizgi kütüphanesinden kopyalanır ve yapıştırılır :

_.delay = function(func, wait) {
  var args = slice.call(arguments, 2);
  return setTimeout(function(){ return func.apply(null, args); }, wait);
};

SetTimeout tarafından çağrılan işleve istediğiniz kadar argüman iletebilirsiniz ve setTimeout'u çağırdığınızda işlevinize iletilen bağımsız değişkenlerin değeri setTimeout'u çağırdığınızda dondurulur; setTimeout () çağrıldığında ve zaman aşımına uğradığında, bu ... artık çok sinir bozucu değil :)

İşte ne demek istediğimi görebileceğiniz bir keman .


7
Bu cevap aslında işe yarıyor ama benim yapmadığım bir kütüphane var gibi görünüyor. İşte çalışması için küçük bir düzeltme: slice.call yerine Array.prototype.slice.call (argümanlar, 2) kullanın
Melanie

7
@Melanie "bazı kütüphane"? Cevabın alt çizgi kütüphanesi olduğunu söyledim - underscorejs.org . Ama evet, Array.prototype.slice bu kütüphanenin içinde dilimlenmek için takma adlıdır, bu yüzden bunu kullanmıyorsanız kendiniz yapmanız gerekir, iyi nokta :)
David Meister

38

Son zamanlarda setTimeoutbir döngüde a kullanmaya ihtiyaç duyduğu benzersiz duruma rastladım . Bunu anlamak, parametreleri nasıl aktaracağınızı anlamanıza yardımcı olabilir setTimeout.

Yöntem 1

Sukima'nın önerisine göre forEachve kullanın :Object.keys

var testObject = {
    prop1: 'test1',
    prop2: 'test2',
    prop3: 'test3'
};

Object.keys(testObject).forEach(function(propertyName, i) {
    setTimeout(function() {
        console.log(testObject[propertyName]);
    }, i * 1000);
});

Bu yöntemi tavsiye ederim.

Yöntem 2

Kullanım bind:

var i = 0;
for (var propertyName in testObject) {
    setTimeout(function(propertyName) {
        console.log(testObject[propertyName]);
    }.bind(this, propertyName), i++ * 1000);
}

JSFiddle: http://jsfiddle.net/MsBkW/

Yöntem 3

Veya kullanamıyorsanız forEachveya bindbir IIFE kullanın :

var i = 0;
for (var propertyName in testObject) {
    setTimeout((function(propertyName) {
        return function() {
            console.log(testObject[propertyName]);
        };
    })(propertyName), i++ * 1000);
}

Yöntem 4

Ancak IE <10'u umursamıyorsanız, Fabio'nun önerisini kullanabilirsiniz :

var i = 0;
for (var propertyName in testObject) {
    setTimeout(function(propertyName) {
        console.log(testObject[propertyName]);
    }, i++ * 1000, propertyName);
}

Yöntem 5 (ES6)

Blok kapsamındaki bir değişkeni kullanın:

let i = 0;
for (let propertyName in testObject) {
    setTimeout(() => console.log(testObject[propertyName]), i++ * 1000);
}

Yine de ES6 Object.keysile kullanmanızı tavsiye ederim forEach.


2
Not: .bindIE8 ve altı için çalışmaz [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Schien'in çözümünü kullanarak bitirdim: stackoverflow.com/a/21213723/1876899
cjspurgeon

1
Eğer kullanan bir ortamda o bindzaman da sunan bir ortamda Object.keysve forEach. For döngüsünü kaybedebilir ve süreçte "serbest" (bir taş serbest kaynaksız değil iki kuşta olduğu gibi) fonksiyon kapsamı elde edebilirsiniz.
Sukima

@David Sherret daha önce kullanmadıysanız kesinlikle asynckütüphaneye göz atın ( github.com/caolan/async ). Sails'de yaygın olarak kullanıyoruz ve son 2 yıldır harika sonuçlar elde ettik. Hem paralel ve asenkron için serideki yöntemler sağlar forEach, map, reducevb
mikermcneil

25

Hobblin bunu zaten soru üzerine yorumladı, ama gerçekten bir cevap olmalı!

Kullanılması Function.prototype.bind()(ayarlamak mümkün olan avantaj ile bunu yapmak en temiz ve en esnek yoldur thisbağlamı):

setTimeout(postinsql.bind(null, topicId), 4000);

Daha fazla bilgi için şu MDN bağlantılarına bakın:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041 https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function / bağlama # With_setTimeout


bu bağlam ilk bağlama argümanı ile aktarılabilirsetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano

@GiuseppeGalano tamamen, cevabımda bahsettim, ama bu örnek için gerekli değil :)
dain

Kısmi uygulamalar üzerinde kaç parlaklığı kullanarak büyüleyici bind. Gerçekten bazı okunabilir kodlar yapar.
Sukima

bind () yalnızca IE9 + 'dan desteklenir, bu nedenle bu yaklaşım <IE9
Sanjeev

@Sanjeev Eski IE'de çalışmak için ES5 şim kullanın: github.com/es-shims/es5-shim
gregers

17

Bazı cevaplar doğru ama kıvrıktır.

Bu soruyu 4 yıl sonra tekrar cevaplıyorum, çünkü tam olarak bu soruyu çözmek için aşırı karmaşık kodlarla karşılaşıyorum. Zarif bir çözüm var.

Her şeyden önce, yavaş bir "eval" işlevine etkili bir çağrı çağırdığından, setTimeout çağrılırken ilk parametre olarak bir dizeyi iletmeyin.

Peki bir parametreyi zaman aşımı fonksiyonuna nasıl geçiririz? Kapanış kullanarak:

settopic=function(topicid){
  setTimeout(function(){
    //thanks to closure, topicid is visible here
    postinsql(topicid);
  },4000);
}

...
if (xhr.readyState==4){
  settopic(xhr.responseText);
}

Bazıları zaman aşımı işlevini çağırırken anonim işlev kullanılmasını önerdi:

if (xhr.readyState==4){
  setTimeout(function(){
    settopic(xhr.responseText);
  },4000);
}

Sözdizimi işe yarıyor. Ancak settopik çağrıldığında, yani 4 saniye sonra, XHR nesnesi aynı olmayabilir. Bu nedenle değişkenleri önceden bağlamak önemlidir .


1
Okumaktan biraz farklı, okunabilir bir çözüm için +1. Settopic işlevi içinde setTimeout varken, setTimeout işlevi içinde fDelayed (settopic) işlevim var.
Dominic

11

Cevabım:

setTimeout((function(topicId) {
  return function() {
    postinsql(topicId);
  };
})(topicId), 4000);

Açıklama:

Oluşturulan anonim işlev başka bir anonim işlev döndürür. Bu işlevin başlangıçta iletilene erişimi vardır topicId, bu nedenle hata yapmaz. İlk anonim işlev hemen çağrılır, iletilir topicId, bu nedenle gecikmeli kayıtlı işleve erişimtopicId , içeri aktarılır , çağrı sırasında, kapaklar aracılığıyla .

VEYA

Bu temel olarak şuna dönüşür:

setTimeout(function() {
  postinsql(topicId); // topicId inside higher scope (passed to returning function)
}, 4000);

EDIT: Aynı cevabı gördüm, bu yüzden ona bakın. Ama cevabını çalmadım! Sadece bakmayı unuttum. Açıklamayı okuyun ve kodun anlaşılmasına yardımcı olup olmadığını görün.


Bu en iyi cevap. Bu çözümlerin çoğu zaman aşımına bile uymayacak. Ancak, parantez içindeki ilk anonim işlevi neden sarıyorsunuz? Bunu başarmak için gerekli olduklarını sanmıyorum.
Robert Henderson

bu en iyi cevaptır but, ancak bir klon yapmak zorunda kalmıştır, çünkü benzeri değerler topicIddeğiştiğinde zaman aşımı değeri de değişir. Bir klon
çözüldü

10

değiştirmek

 setTimeout("postinsql(topicId)", 4000);

ile

 setTimeout("postinsql(" + topicId + ")", 4000);

veya daha iyisi, dize ifadesini anonim bir işlevle değiştirin

 setTimeout(function () { postinsql(topicId); }, 4000);

DÜZENLE:

Brownstone'un yorumu yanlış, Firebug konsolunda çalıştırarak gösterildiği gibi, bu amaçlandığı gibi çalışacaktır

(function() {
  function postinsql(id) {
    console.log(id);
  }
  var topicId = 3
  window.setTimeout("postinsql(" + topicId + ")",4000); // outputs 3 after 4 seconds
})();

setTimeoutBu eval()dize çağıracak ve bunun yerine bir işlevi geçirecek gibi bir dize geçirmekten kaçınmalısınız diğerleri ile anlaşıyorum .


Bunun nedeni çalışmaz sonuç postinsql (topicId) ait setTimeout tarafından yürütülecektir. İlk cevaptaki gibi bir işleve sarmanız veya Prototype'ın .curry () - setTimeout (postinsql.curry (topidId), 4000) gibi bir yardımcı kullanmanız gerekir;
shuckster

2
@brownstone: Bu yanlış. Zaman aşımı tetiklendiğinde dize değerlendirilecektir.
Miles

9

Parametreyi setTimeout geri arama işlevine şu şekilde aktarabilirsiniz:

setTimeout (işlev, milisaniye, param1, param2, ...)

Örneğin.

function myFunction() {
  setTimeout(alertMsg, 3000, "Hello");
}

function alertMsg(message) {
    alert(message)
}

1
Biri bana bu cevabın neden tercih edilmediğini söyleyebilir mi? bence bu en basit yol! As simple assetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Mazhar Zandsalimi

1
Evet! Bu kabul edilen cevap olmalı. MDN'den: developer.mozilla.org/tr-TR/docs/Web/API/…
Han


5

Bu soru sorulduğundan beri 10 yıl geçtiğini biliyorum, ama yine de, buraya kadar kaydırdıysanız, hala bazı sorunlarla karşı karşıya olduğunuzu varsayıyorum. Meder Omuraliev'in çözümü en basit olanıdır ve çoğumuza yardımcı olabilir, ancak herhangi bir bağlanmak istemeyenler için burada:

  1. SetTimeout için Param kullanın
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Hemen Çağırılan İşlev İfadesini Kullan (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Sorunun çözümü
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}

4

Eski olduğunu biliyorum ama buna (tercih edilen) lezzetimi eklemek istedim.

Bunu başarmak için oldukça okunabilir bir yol topicId, sırayla konu kimliğini dahili referans için argüman kullanan bir işleve geçmek olduğunu düşünüyorum . topicIdKısa bir süre sonra dışarıdan değiştirilse bile bu değer değişmez .

var topicId = xmlhttp.responseText;
var fDelayed = function(tid) {
  return function() {
    postinsql(tid);
  };
}
setTimeout(fDelayed(topicId),4000);

veya kısa:

var topicId = xmlhttp.responseText;
setTimeout(function(tid) {
  return function() { postinsql(tid); };
}(topicId), 4000);

4

David Meister'ın cevabı, setTimeout () çağrısından hemen sonra ancak anonim işlev çağrılmadan önce değişebilecek parametrelerle ilgileniyor gibi görünüyor. Ama çok hantal ve çok açık değil. IIFE'yi kullanarak hemen hemen aynı şeyi yapmanın zarif bir yolunu keşfettim (hemen işlev ifadesi).

Aşağıdaki örnekte, currentListdeğişken, gecikmeli fonksiyon çağrılıncaya kadar kapanmasına kaydeden IIFE'ye geçirilir. Değişken currentListgösterilen koddan hemen sonra değişse bile ,setInterval() , doğru olanı yapar.

Bu IIFE tekniği olmadan, setTimeout()işlev DOM'daki her h2öğe için kesinlikle çağrılacaktır , ancak tüm bu çağrılar yalnızca son h2 öğenin metin değerini görecektir .

<script>
  // Wait for the document to load.
  $(document).ready(function() {
  $("h2").each(function (index) {

    currentList = $(this).text();

    (function (param1, param2) {
        setTimeout(function() {
            $("span").text(param1 + ' : ' + param2 );
        }, param1 * 1000);

    })(index, currentList);
  });
</script>

4

Genel olarak, bir işlevi belirli parametrelerle geri arama olarak iletmeniz gerekiyorsa, daha yüksek dereceli işlevleri kullanabilirsiniz. Bu ES6 ile oldukça zarif:

const someFunction = (params) => () => {
  //do whatever
};

setTimeout(someFunction(params), 1000);

Veya someFunctionilk sipariş ise:

setTimeout(() => someFunction(params), 1000); 

bu çok uyumsuz
user151496

Gerçekten zarif! Teşekkürler
Velojet

3

TopicId'nin hata mesajı başına "tanımlanmadığı" nedeninin, setTimeout yürütüldüğünde yerel bir değişken olarak var olduğunu, ancak postinsql'e gecikmeli çağrı gerçekleştiğinde olmadığını unutmayın. Değişken yaşam, özellikle bir nesne referansı olarak "bu" iletmek gibi bir şey denerken özellikle dikkat edilmesi önemlidir.

SetTimeout işlevine üçüncü bir parametre olarak topicId iletebildiğini duydum. Çok fazla ayrıntı verilmiyor, ancak çalışmasını sağlamak için yeterli bilgiye sahibim ve Safari'de başarılı. Gerçi "milisaniye hatası" hakkında ne demek bilmiyorum. Buradan kontrol edin:

http://www.howtocreate.co.uk/tutorials/javascript/timers


3

Bu aşamayı nasıl çözdüm?

aynen böyle :

setTimeout((function(_deepFunction ,_deepData){
    var _deepResultFunction = function _deepResultFunction(){
          _deepFunction(_deepData);
    };
    return _deepResultFunction;
})(fromOuterFunction, fromOuterData ) , 1000  );

setTimeout bir işleve bir referans beklemek, bu yüzden benim verileri yorumlamak ve verilerimin iyi bir örneği ile bir işlev döndürmek, bir kapatma oluşturdu!

Belki bu kısmı geliştirebilirsiniz:

_deepFunction(_deepData);

// change to something like :
_deepFunction.apply(contextFromParams , args); 

Ben krom, firefox ve IE üzerinde test ve iyi yürütmek, ben performans hakkında bilmiyorum ama çalışması gerekiyordu.

bir örnek testi:

myDelay_function = function(fn , params , ctxt , _time){
setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.call(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// the function to be used :
myFunc = function(param){ console.log(param + this.name) }
// note that we call this.name

// a context object :
myObjet = {
    id : "myId" , 
    name : "myName"
}

// setting a parmeter
myParamter = "I am the outer parameter : ";

//and now let's make the call :
myDelay_function(myFunc , myParamter  , myObjet , 1000)

// this will produce this result on the console line :
// I am the outer parameter : myName

Belki imzayı daha uyumlu hale getirmek için değiştirebilirsiniz:

myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.apply(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// and try again :
for(var i=0; i<10; i++){
   myNass_setTimeOut(console.log ,1000 , [i] , console)
}

Ve son soruya orijinal soruyu cevaplamak için:

 myNass_setTimeOut( postinsql, 4000, topicId );

Umarım yardımcı olabilir!

ps: üzgünüm ama ingilizce bu benim ana dilim değil!


Bu, diğer cevaplara kıyasla aşırı derecede karmaşıktır.
Dan Dascalescu

3

bu tüm tarayıcılarda çalışır (IE tuhaftır)

setTimeout( (function(x) {
return function() {
        postinsql(x);
    };
})(topicId) , 4000);

3

Eğer değişkeni param olarak iletmek istiyorsanız bunu deneyelim

gereksinim işlevse ve parmas olarak var ise bunu deneyin

setTimeout((param1,param2) => { 
     alert(param1 + param2);
     postinsql(topicId);
},2000,'msg1', 'msg2')

gereksinim yalnızca parametre olarak değişkense bunu deneyin

setTimeout((param1,param2) => { alert(param1 + param2) },2000,'msg1', 'msg2')

Bunu ES5 ve ES6 ile deneyebilirsiniz


2

Bunun gibi 'Apply ()' işlevinin varsayılan işlevselliğini deneyebilir, dizide gereksiniminiz olarak daha fazla sayıda argüman iletebilirsiniz

function postinsql(topicId)
{
  //alert(topicId);
}
setTimeout(
       postinsql.apply(window,["mytopic"])
,500);

1

setTimeout, WHAT WG tarafından tanımlanan DOM'nin bir parçasıdır.

https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html

İstediğiniz yöntem: -

handle = self.setTimeout( handler [, timeout [, arguments... ] ] )

Zaman aşımı milisaniyesinden sonra işleyiciyi çalıştırmak için bir zaman aşımı zamanlar. Tüm argümanlar doğrudan işleyiciye aktarılır.

setTimeout(postinsql, 4000, topicId);

Görünüşe göre, IE10'da ekstra argümanlar desteklenmektedir. Alternatif olarak, kullanabilirsiniz setTimeout(postinsql.bind(null, topicId), 4000);, ancak ekstra argümanlar geçirmek daha basittir ve bu tercih edilir.

Geçmiş factoid: VBScript günlerinde, JScript'te, setTimeout'un üçüncü parametresi dize olarak varsayılan olarak "JScript" olarak kullanılan, ancak "VBScript" kullanma seçeneğiyle dildi. https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)


0

@ Jiri Vetyska gönderi için teşekkürler, ancak örneğinizde bir sorun var. Üzerine gelinen hedefi (bu) zaman aşımına uğramış bir işleve geçirmem gerekiyordu ve yaklaşımınızı denedim. IE9'da test edilmiştir - çalışmaz. Ayrıca biraz araştırma yaptım ve burada da belirtildiği gibi görünüyor belirtildiği gibi üçüncü parametre kullanılan kod dilidir. Ek parametrelerden bahsedilmiyor.

Böylece, @ meder'ın cevabını takip ettim ve bu kodla ilgili sorunumu çözdüm:

$('.targetItemClass').hover(ItemHoverIn, ItemHoverOut);

function ItemHoverIn() {
 //some code here
}

function ItemHoverOut() {
    var THIS = this;
    setTimeout(
        function () { ItemHoverOut_timeout(THIS); },
        100
    );
}
function ItemHoverOut_timeout(target) {
    //do something with target which is hovered out
}

Umarım bu başka biri için yararlıdır.


0

IE'deki üçüncü optonal parametresiyle ilgili bir sorun olduğundan ve kapanışların kullanılması değişkenleri değiştirmemizi (örneğin bir döngüde) ve yine de istenen sonucu elde etmemizi önlediğinden, aşağıdaki çözümü öneririm.

Şu şekilde özyineleme kullanmayı deneyebiliriz:

var i = 0;
var hellos = ["Hello World1!", "Hello World2!", "Hello World3!", "Hello World4!", "Hello World5!"];

if(hellos.length > 0) timeout();

function timeout() {                
    document.write('<p>' + hellos[i] + '<p>');
    i++;
    if (i < hellos.length)
        setTimeout(timeout, 500);
}

Bu değişkenleri başka hiçbir şeyin değiştirmediğinden ve sonsuz tekrarlamayı önlemek için uygun bir özyineleme koşulu yazdığımızdan emin olmalıyız.


0

// Bunlar çok basit ve özlü üç cevaptır:

function fun() {
    console.log(this.prop1, this.prop2, this.prop3);
}

let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };

let bound = fun.bind(obj);

setTimeout(bound, 3000);

 // or

function funOut(par1, par2, par3) {

  return function() { 

    console.log(par1, par2, par3);

  }
};

setTimeout(funOut('one', 'two', 'three'), 5000);

 // or

let funny = function(a, b, c) { console.log(a, b, c); };

setTimeout(funny, 2000, 'hello', 'worldly', 'people');

0

Soruyu cevaplamak ama 2 argüman ile basit bir ekleme fonksiyonu.

var x = 3, y = 4;

setTimeout(function(arg1, arg2) { 
      delayedSum(arg1, arg2);
}(x, y), 1000);

function delayedSum(param1, param2) {
     alert(param1 + param2); // 7
}

0

TırnaklarısetTimeOut işlev çağrınızdan şu şekilde kaldırmanız gerekir :

setTimeout(postinsql(topicId),4000);

-1

Bence sen istiyorsun:

setTimeout("postinsql(" + topicId + ")", 4000);

1
Ben sadece bu işe yaramaz (her zaman bir 'işlev tanımlanmadı' hatasıyla sonuçlanır) durumlarda çalışır ama anonim işlevi kullanarak çalışır. Herkesin yukarıdaki sözdiziminin her zaman çalışması gerektiğini söylediği göz önüne alındığında, sinir bozucu. (jQuery bir şekilde 'dize olarak alıntı yap' yönteminin önüne geçebilir mi?)
DA.

6
Diyelim topicId bir işlev ... Veya bir nesne. Bu işe yaramaz!
Serafeim

Bu yönteme gerçekten devam etmek istiyorsanız, JSON.stringifynormal nesneler ve diziler için kullanın ve ardından JSON.parseişlevin içinde kullanın . Ancak, nesnenin yöntemleri varsa tüm davranışlar kaybolacaktır.
DarthCadeus

-2

// Bunlar çok basit ve özlü üç cevaptır:

function fun() {
    console.log(this.prop1, this.prop2, this.prop3);
}

let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };

let bound = fun.bind(obj);

setTimeout(bound, 3000);

 // or

function funOut(par1, par2, par3) {

  return function() { 

    console.log(par1, par2, par3);

  }
};

setTimeout(funOut('one', 'two', 'three'), 5000);

 // or

let funny = function(a, b, c) { console.log(a, b, c); };

setTimeout(funny, 2000, 'hello', 'worldly', 'people');
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.