Come posso passare un parametro a un callback setTimeout ()?


826

Ho del codice JavaScript che assomiglia a:

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

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

topicIdViene visualizzato un errore non definito Tutto funzionava prima di utilizzare la setTimeout()funzione.

Voglio che la mia postinsql(topicId)funzione venga chiamata dopo qualche tempo. Cosa dovrei fare?


75
fa un po 'male commentare un argomento così vecchio ma devo solo offrire una terza versione (che secondo me è molto più pulita): setTimeout (postinsql.bind (null, topicId), 4000)
Hobblin

14
@Hobblin: perché farebbe male a mettere le cose in chiaro? Non farebbe male agli altri più atterrare su questa domanda popolare e vedere il vecchio stile di chiamata sconsigliato?
Dan Dascalescu,


@dbliss Il mio suggerimento è già stato menzionato in molte delle risposte e aggiunto come risposta qui: stackoverflow.com/a/15620038/287130 Ma sono contento che il mio suggerimento sia apprezzato;)
Hobblin

@Hobblin ah, molte grazie per averlo sottolineato. mi sono sfogliato alla ricerca di una risposta inviata da te e l'ho persa.
Dbliss,

Risposte:


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

È necessario alimentare una funzione anonima come parametro anziché come stringa, quest'ultimo metodo non dovrebbe nemmeno funzionare secondo le specifiche ECMAScript ma i browser sono solo indulgenti. Questa è la soluzione corretta, non fare mai affidamento sul passaggio di una stringa come "funzione" quando si utilizza setTimeout()o setInterval(), è più lento perché deve essere valutato e non è giusto.

AGGIORNARE:

Come Hobblin ha detto nei suoi commenti alla domanda, ora puoi passare argomenti alla funzione all'interno di setTimeout usando Function.prototype.bind().

Esempio:

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

30
window.setTimeoutè un metodo DOM e come tale non è definito dalla specifica ECMAScript. Il passaggio di una stringa ha sempre funzionato nei browser ed è di fatto uno standard - in effetti, la possibilità di passare un oggetto funzione è stata aggiunta in seguito, con JavaScript 1.2 - fa esplicitamente parte della bozza delle specifiche HTML5 ( whatwg.org/specs/web -apps / current-work / multipage / ... ). Tuttavia, l'utilizzo di una stringa anziché di un oggetto funzione è generalmente considerato stile scadente perché è essenzialmente una forma di ritardo eval().
Miglia,

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

12
Cosa accadrebbe se topicId venisse modificato dopo l'impostazione del timeout, ma prima che venga chiamata la funzione?
pilau,

22
@pilau questo è esattamente il mio problema: se le variabili utilizzate nella funzione anonima cambiano prima del timeout (come in un ciclo for), cambierà anche all'interno della funzione. Quindi, nel mio esempio, l'impostazione di 5 timeout diversi in un ciclo for ha effettivamente finito con le stesse variabili. Fai attenzione quando usi questa risposta!
Cristian,

10
@pilau usando un'altra chiusura aiuterà topicId = 12; funzione postinsql (topicId) {console.log (topicId); } funzione setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); TopicId = 13;
Halis Yılboğa il

727

Nei browser moderni, "setTimeout" riceve un terzo parametro che viene inviato come parametro alla funzione interna alla fine del timer.

Esempio:

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

Più dettagli:


56
Non sono sicuro del perché questa risposta non sia stata selezionata come la migliore. L'uso di una funzione anonima funziona, certo, ma se puoi semplicemente passare un terzo parametro nella chiamata alla funzione setTimeout originale ... perché no?
Kris Schouw,

54
Perché non funziona ancora nelle versioni di IE allo stato selvatico.
Aaron,

4
Questa risposta in realtà mi ha permesso di passare un oggetto evento, gli altri metodi no. Avevo già una funzione anonima.
Glenn Plas,

27
Risposta di gran lunga migliore. Se si dispone di codice che modifica il parametro tra la chiamata "setTimeout" e l'esecuzione effettiva della funzione anonima - la funzione anonima riceverà un valore modificato, non quello che era al momento della chiamata setTimeout. es: for (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } questo registrerà "100" 100 volte (testato su FF). La risposta attuale aiuta a evitarlo.
radice

1
In base a developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout gli argomenti di callback per Internet Explorer sono supportati solo nelle versioni> = 10, fai attenzione come in molti siti ie8 e ie9 ottiene ancora una condivisione rilevante.
le0diaz,

155

Dopo aver effettuato alcune ricerche e test, l'unica implementazione corretta è:

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

setTimeout passerà tutti i parametri extra alla tua funzione in modo che possano essere elaborati lì.

La funzione anonima può funzionare per cose molto basilari, ma all'interno di un oggetto in cui devi usare "this", non c'è modo di farlo funzionare. Qualsiasi funzione anonima cambierà "questo" per puntare alla finestra, quindi perderai il riferimento all'oggetto.


24
È con tristezza nel mio cuore che devo informare: questo non funziona in Internet Explorer. : / Tutti i parametri extra vengono definiti indefiniti.
Amalgovinus,

6
Uso solovar that = this; setTimeout( function() { that.foo(); }, 1000);
Ed Williams il

2
Questo è corretto ed è specificato in HTML5. whatwg.org/specs/web-apps/current-work/multipage/…
Garrett

4
Questa è esattamente la stessa risposta di Fabio .
Dan Dascalescu,

1
In base a developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout gli argomenti di callback per Internet Explorer sono supportati solo nelle versioni> = 10, fai attenzione come in molti siti ie8 e ie9 ottiene ancora una condivisione rilevante.
le0diaz,

45

Questa è una domanda molto antica con una risposta già "corretta", ma ho pensato di menzionare un altro approccio che nessuno ha menzionato qui. Questo viene copiato e incollato dall'eccellente libreria di sottolineatura :

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

Puoi passare tutti gli argomenti che desideri alla funzione chiamata da setTimeout e come bonus aggiuntivo (bene, di solito un bonus) il valore degli argomenti passati alla tua funzione viene congelato quando chiami setTimeout, quindi se cambiano valore a un certo punto tra quando viene chiamato setTimeout () e quando scade, beh ... non è più così orribilmente frustrante :)

Ecco un violino in cui puoi vedere cosa intendo.


7
Quella risposta funziona davvero ma sembra che tu abbia una biblioteca che io non ho. Ecco la piccola soluzione per farlo funzionare: invece di slice.call, usa Array.prototype.slice.call (argomenti, 2)
Melanie,

7
@Melanie "qualche biblioteca"? Nella risposta ho detto che è la libreria di sottolineatura - underscorejs.org . Ma sì, Array.prototype.slice è aliasato per tagliare all'interno di quella libreria, quindi devi farlo da solo se non lo stai usando, buon posto :)
David Meister

38

Di recente mi sono imbattuto nella singolare situazione della necessità di utilizzare un setTimeoutin un ciclo . Capire questo può aiutarti a capire come passare i parametri setTimeout.

Metodo 1

Usa forEache Object.keys, come suggerito da Sukima :

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

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

Consiglio questo metodo

Metodo 2

Utilizzare 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/

Metodo 3

O se non puoi usare forEacho bind, usa un IIFE :

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

Metodo 4

Ma se non ti interessa IE <10, puoi usare il suggerimento di Fabio :

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

Metodo 5 (ES6)

Utilizzare una variabile con ambito di blocco:

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

Anche se consiglierei comunque di utilizzarlo Object.keyscon forEachES6.


2
Nota: .bindnon funzionerà con IE8 e versioni precedenti [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Ho finito per usare la soluzione di Schien: stackoverflow.com/a/21213723/1876899
cjspurgeon

1
Se sei in un ambiente che utilizza, bindallora sei anche in un ambiente che offre Object.keyse forEach. È possibile perdere il ciclo for e ottenere un ambito di funzione "libero" (come in due uccelli con una pietra libera non risorse libere) nel processo.
Sukima,

@David Sherret se non l'hai mai usato prima, dai un'occhiata alla asynclibreria ( github.com/caolan/async ). Lo utilizziamo ampiamente in Sails e abbiamo ottenuto ottimi risultati negli ultimi 2 anni. Esso fornisce metodi in parallelo e in serie per asincrono forEach, map, reduce, ecc
mikermcneil

25

Hobblin lo ha già commentato sulla domanda, ma dovrebbe essere davvero una risposta!

L'utilizzo Function.prototype.bind()è il modo più pulito e flessibile per farlo (con l'ulteriore vantaggio di poter impostare il thiscontesto):

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

Per ulteriori informazioni, consultare questi collegamenti MDN:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041 https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function / bind # With_setTimeout


questo contesto può essere superato con il primo argomento del legamesetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano,

@GiuseppeGalano totalmente, l'ho menzionato nella mia risposta, ma non è necessario per questo esempio :)
dain

Affascinante quanta lucentezza su applicazioni parziali utilizza bind. Rende davvero un po 'di codice leggibile.
Sukima,

bind () è supportato solo da IE9 +, quindi questo approccio non funzionerà per <IE9
Sanjeev

@Sanjeev Usa lo shim ES5 per farlo funzionare negli IE precedenti: github.com/es-shims/es5-shim
gregers

17

Alcune risposte sono corrette ma contorte.

Sto rispondendo di nuovo a questo, 4 anni dopo, perché mi imbatto ancora in un codice troppo complesso per risolvere esattamente questa domanda. C'è una soluzione elegante.

Prima di tutto, non passare una stringa come primo parametro quando si chiama setTimeout perché invoca effettivamente una chiamata alla funzione "eval" lenta.

Quindi, come passiamo un parametro a una funzione di timeout? Usando la chiusura:

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

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

Alcuni hanno suggerito di utilizzare la funzione anonima quando si chiama la funzione di timeout:

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

La sintassi funziona. Ma quando viene chiamato settopic, cioè 4 secondi dopo, l'oggetto XHR potrebbe non essere lo stesso. Pertanto è importante pre-associare le variabili .


1
+1 per una soluzione leggibile, leggermente diversa dalla mia. Mentre hai setTimeout all'interno della funzione settopic, ho la funzione fDelayed (il tuo settopic) all'interno della funzione setTimeout.
Dominic,

11

La mia risposta:

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

Spiegazione:

La funzione anonima creata restituisce un'altra funzione anonima. Questa funzione ha accesso a quella originariamente passata topicId, quindi non farà errori. La prima funzione anonima viene immediatamente chiamata, passando topicId, quindi la funzione registrata con un ritardo ha accesso topicIdal momento della chiamata, attraverso le chiusure.

O

Questo sostanzialmente si converte in:

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

EDIT: ho visto la stessa risposta, quindi guarda la sua. Ma non ho rubato la sua risposta! Ho appena dimenticato di guardare. Leggi la spiegazione e vedi se aiuta a capire il codice.


Questa è la risposta migliore Molte di queste soluzioni non onoreranno nemmeno il timeout. Tuttavia, perché stai racchiudendo la prima funzione anonima tra parentesi? Non penso che siano necessari per raggiungere questo obiettivo.
Robert Henderson,

questa è la risposta migliore 👍, ma ha dovuto fare un clone perché quando valori come topicIdvengono modificati anche il valore nel timeout cambia. Un clone lo
aggiustò

10

Sostituire

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

con

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

o meglio ancora, sostituire l'espressione stringa con una funzione anonima

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

MODIFICARE:

Il commento di Brownstone non è corretto, funzionerà come previsto, come dimostrato eseguendolo nella console Firebug

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

Nota che sono d'accordo con gli altri a cui dovresti evitare di passare una stringa in setTimeoutquanto ciò chiamerà eval()la stringa e invece passerà una funzione.


Questo non funzionerà perché il risultato di postinsql (topicId) verrà eseguito da setTimeout. Devi avvolgerlo in una funzione come con la prima risposta, oppure usare un aiuto come .curry () - setTimeout di Prototype (postinsql.curry (topidId), 4000);
shuckster,

2
@brownstone: non è corretto. La stringa verrà valutata all'attivazione del timeout.
Miglia,

9

È possibile passare il parametro alla funzione di callback setTimeout come:

setTimeout (funzione, millisecondi, param1, param2, ...)

per esempio.

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

function alertMsg(message) {
    alert(message)
}

1
Qualcuno può dirmi perché questa risposta non è quella preferita? questo è il modo più semplice secondo me! Semplice comesetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Mazhar Zandsalimi,

1
Si! Questa dovrebbe essere la risposta accettata. Da MDN: developer.mozilla.org/en-US/docs/Web/API/…
Han


5

So che sono passati 10 anni da quando è stata posta questa domanda, ma comunque, se hai fatto scorrere fino a qui, suppongo che stai ancora affrontando qualche problema. La soluzione di Meder Omuraliev è la più semplice e può aiutare la maggior parte di noi, ma per coloro che non vogliono avere alcun legame, eccola qui:

  1. Utilizzare Param per setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Usa espressione funzione invocata immediatamente (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Soluzione alla domanda
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

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

4

So che è vecchio ma volevo aggiungere il mio (preferito) sapore a questo.

Penso che un modo abbastanza leggibile per raggiungere questo obiettivo sia passare topicIda una funzione, che a sua volta usa l'argomento per fare riferimento all'ID argomento internamente. Questo valore non cambierà anche se topicIdall'esterno verrà modificato poco dopo.

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

o corto:

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

4

La risposta di David Meister sembra occuparsi dei parametri che possono cambiare immediatamente dopo la chiamata a setTimeout () ma prima che venga chiamata la funzione anonima. Ma è troppo ingombrante e non molto evidente. Ho scoperto un modo elegante di fare praticamente la stessa cosa usando IIFE (espressione di funzione immediatamente invitata).

Nell'esempio seguente, la currentListvariabile viene passata all'IIFE, che la salva nella sua chiusura, fino a quando non viene invocata la funzione ritardata. Anche se la variabile currentListcambia immediatamente dopo il codice mostrato, setInterval()farà la cosa giusta.

Senza questa tecnica IIFE, la setTimeout()funzione verrà sicuramente chiamata per ogni h2elemento nel DOM, ma tutte quelle chiamate vedranno solo il valore di testo dell'ultimo h2 elemento.

<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

In generale, se è necessario passare una funzione come richiamata con parametri specifici, è possibile utilizzare le funzioni di ordine superiore. Questo è piuttosto elegante con ES6:

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

setTimeout(someFunction(params), 1000);

O se someFunctionè il primo ordine:

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

questo è molto incompatibile
user151496

Elegante davvero! Grazie
Velojet

3

Si noti che il motivo topicId "non è stato definito" per il messaggio di errore è che esisteva come variabile locale quando è stato eseguito setTimeout, ma non quando si è verificata la chiamata ritardata a postinsql. La durata variabile è particolarmente importante a cui prestare attenzione, specialmente quando si prova qualcosa come passare "questo" come riferimento a un oggetto.

Ho sentito che puoi passare topicId come terzo parametro alla funzione setTimeout. Non sono stati forniti molti dettagli, ma ho abbastanza informazioni per farlo funzionare ed ha successo in Safari. Non so cosa significano per "errore di millisecondi". Controllalo qui:

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


3

Come ho risolto questo stadio?

proprio così :

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

setTimeout attendo un riferimento a una funzione, quindi l'ho creato in una chiusura, che interpreta i miei dati e restituisce una funzione con una buona istanza dei miei dati!

Forse puoi migliorare questa parte:

_deepFunction(_deepData);

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

L'ho testato su Chrome, Firefox e Internet Explorer e funziona bene, non conosco le prestazioni ma avevo bisogno che funzionasse.

un test di esempio:

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

Forse puoi modificare la firma per renderla più conforme:

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)
}

E infine per rispondere alla domanda originale:

 myNass_setTimeOut( postinsql, 4000, topicId );

Spero che possa aiutare!

ps: scusa ma l'inglese non è la mia lingua madre!


Questo è eccessivamente complicato, rispetto ad altre risposte.
Dan Dascalescu,

3

funziona in tutti i browser (IE è una strana palla)

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

3

se vuoi passare una variabile come param, prova questo

se il requisito è funzione e var come parametri quindi provare questo

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

se il requisito è solo una variabile come parametro allora prova questo

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

Puoi provarlo con ES5 ed ES6


2

Puoi provare la funzionalità predefinita di 'apply ()' come questa, puoi passare più numero di argomenti come requisito nell'array

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

1

setTimeout fa parte del DOM definito da WHAT WG.

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

Il metodo che desideri è: -

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

Pianifica un timeout per l'esecuzione del gestore dopo il timeout millisecondi. Qualsiasi argomento viene passato direttamente al gestore.

setTimeout(postinsql, 4000, topicId);

Apparentemente, in IE10 sono supportati argomenti extra. In alternativa, puoi usare setTimeout(postinsql.bind(null, topicId), 4000);, tuttavia passare argomenti extra è più semplice ed è preferibile.

Factoide storico: ai tempi di VBScript, in JScript, il terzo parametro di setTimeout era il linguaggio, come una stringa, che era impostato per default su "JScript" ma con l'opzione di usare "VBScript". https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)


0

@Jiri Vetyska grazie per il post, ma c'è qualcosa di sbagliato nel tuo esempio. Avevo bisogno di passare il bersaglio che è sospeso (questo) a una funzione scaduta e ho provato il tuo approccio. Testato in IE9 - non funziona. Ho anche fatto alcune ricerche e sembra che, come indicato qui, il terzo parametro sia il linguaggio di script utilizzato. Nessuna menzione di parametri aggiuntivi.

Quindi, ho seguito la risposta di @ meder e ho risolto il mio problema con questo codice:

$('.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
}

Spero che questo sia utile per qualcun altro.


0

Poiché esiste un problema con il terzo parametro optonale in IE e l'utilizzo di chiusure ci impedisce di modificare le variabili (ad esempio in un ciclo) e di ottenere comunque il risultato desiderato, suggerisco la seguente soluzione.

Possiamo provare a usare la ricorsione in questo modo:

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);
}

Dobbiamo assicurarci che nient'altro cambi queste variabili e che scriviamo una condizione di ricorsione adeguata per evitare la ricorsione infinita.


0

// Queste sono tre risposte molto semplici e concise:

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

Rispondere alla domanda ma con una semplice funzione di aggiunta con 2 argomenti.

var x = 3, y = 4;

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

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

0

È necessario rimuovere le virgolette dalla setTimeOutchiamata della funzione in questo modo:

setTimeout(postinsql(topicId),4000);

-1

Penso che tu voglia:

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

1
Mi sono imbattuto in casi in cui semplicemente non funziona (risultando sempre in un errore "funzione non definita") ma l'utilizzo della funzione anonima funziona. Il che è frustrante dato che tutti sembrano dire che la sintassi di cui sopra dovrebbe sempre funzionare. (potrebbe essere che jQuery interferisca in qualche modo con il metodo "quote as string"?)
DA.

6
Supponiamo che topicId sia una funzione ... O un oggetto. Questo non funzionerà!
Serafeim,

Se si desidera veramente procedere con questo metodo, utilizzare JSON.stringifyper oggetti e matrici normali, quindi utilizzare JSON.parseall'interno della funzione. Tuttavia, tutto il comportamento andrà perso se l'oggetto ha dei metodi.
DarthCadeus,

-2

// Queste sono tre risposte molto semplici e concise:

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');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.