Wie kann ich einen Parameter an einen setTimeout () - Rückruf übergeben?

825

Ich habe einen JavaScript-Code, der wie folgt aussieht:

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

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

Ich erhalte einen Fehler, der topicIdnicht definiert ist. Alles hat funktioniert, bevor ich die setTimeout()Funktion verwendet habe.

Ich möchte, dass meine postinsql(topicId)Funktion nach einiger Zeit aufgerufen wird. Was sollte ich tun?

Zeeshan Rang
quelle
75
Es tut ein bisschen weh, ein so altes Thema zu kommentieren, aber ich muss nur eine dritte Version anbieten (die meiner Meinung nach viel sauberer ist): setTimeout (postinsql.bind (null, topicId), 4000)
Hobblin
14
@Hobblin: Warum sollte es weh tun, den Rekord gerade zu stellen? Würde es anderen nicht mehr schaden, auf dieser beliebten Frage zu landen und den alten, entmutigten Anrufstil zu sehen?
Dan Dascalescu
2
Hier ist alles klar: w3schools.com/jsref/met_win_settimeout.asp
Vladislav
@dbliss Mein Vorschlag wurde bereits in mehreren Antworten erwähnt und hier als Antwort hinzugefügt: stackoverflow.com/a/15620038/287130 Aber ich bin froh, dass mein Vorschlag geschätzt wird;)
Hobblin
@Hobblin ah, vielen Dank für den Hinweis. Ich hatte nach einer Antwort gesucht, die von Ihnen gepostet wurde, und diese verpasst.
Dbliss

Antworten:

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

Sie müssen eine anonyme Funktion als Parameter anstelle einer Zeichenfolge eingeben. Die letztere Methode sollte nicht einmal gemäß der ECMAScript-Spezifikation funktionieren, aber die Browser sind nur nachsichtig. Dies ist die richtige Lösung. Verlassen Sie sich niemals darauf, einen String als 'Funktion' zu übergeben, wenn Sie setTimeout()oder verwenden setInterval(). Er ist langsamer, weil er ausgewertet werden muss und einfach nicht richtig ist.

AKTUALISIEREN:

Wie Hobblin in seinen Kommentaren zur Frage sagte , können Sie jetzt Argumente an die Funktion in setTimeout mit übergeben Function.prototype.bind().

Beispiel:

setTimeout(postinsql.bind(null, topicId), 4000);
meder omuraliev
quelle
30
window.setTimeoutist eine DOM-Methode und als solche nicht in der ECMAScript-Spezifikation definiert. Das Übergeben einer Zeichenfolge hat in Browsern immer funktioniert und ist ein De-facto- Standard. Die Möglichkeit, ein Funktionsobjekt zu übergeben, wurde später mit JavaScript 1.2 hinzugefügt. Es ist explizit Teil der HTML5-Entwurfsspezifikation ( whatwg.org/specs/web) -apps / current-work / mehrseitig /… ). Die Verwendung einer Zeichenfolge anstelle eines Funktionsobjekts wird jedoch im Allgemeinen als schlechter Stil angesehen, da es sich im Wesentlichen um eine Form der Verzögerung handelt eval().
Meilen
2
var temp = setTimeout (function () {postinsql (topicId);}, 4000); clearTimeout (temp); ??
Josh Mc
12
Was würde passieren, wenn die topicId geändert wird, nachdem das Timeout festgelegt wurde, aber bevor die Funktion aufgerufen wird?
Pilau
22
@pilau das ist genau mein Problem: Wenn sich die in der anonymen Funktion verwendeten Variablen vor dem Timeout ändern (z. B. in einer for-Schleife), ändert sich dies auch innerhalb der Funktion. In meinem Beispiel wurden beim Festlegen von 5 verschiedenen Zeitüberschreitungen in einer for-Schleife tatsächlich dieselben Variablen verwendet. Seien Sie vorsichtig, wenn Sie diese Antwort verwenden!
Cristian
10
@pilau mit einem anderen Abschluss hilft topicId = 12; Funktion postinsql (topicId) {console.log (topicId); } function setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13;
Halis Yılboğa
727

In modernen Browsern empfängt das "setTimeout" einen dritten Parameter, der am Ende des Timers als Parameter an die interne Funktion gesendet wird.

Beispiel:

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

Mehr Details:

Fabio Phms
quelle
56
Ich bin mir nicht sicher, warum diese Antwort nicht als die beste ausgewählt wurde. Die Verwendung einer anonymen Funktion funktioniert zwar, aber wenn Sie einfach einen dritten Parameter an den ursprünglichen Funktionsaufruf setTimeout übergeben können ... warum nicht?
Kris Schouw
54
Weil es in IE-Versionen immer noch nicht sehr viel in freier Wildbahn funktioniert.
Aaron
4
Diese Antwort hat es mir tatsächlich ermöglicht, ein Ereignisobjekt zu übergeben, die anderen Methoden jedoch nicht. Ich hatte bereits eine anonyme Funktion.
Glenn Plas
27
Bei weitem bessere Antwort. Wenn Sie Code haben, der Ihren Parameter zwischen dem Aufruf "setTimeout" und der tatsächlichen Ausführung der anonymen Funktion ändert, erhält die anonyme Funktion einen geänderten Wert, nicht den zum Zeitpunkt des Aufrufs von setTimeout. zB: für (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } Dies protokolliert 100 Mal "100" (getestet auf FF). Die aktuelle Antwort hilft, dies zu vermeiden.
Wurzel
1
Laut developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout werden die Rückrufargumente für Internet Explorer nur in Versionen> = 10 unterstützt. Seien Sie vorsichtig, da auf vielen Websites ie8 und ie9 immer noch relevante Anteile erhalten.
Le0diaz
154

Nach einigen Recherchen und Tests ist die einzig richtige Implementierung:

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

setTimeout übergibt alle zusätzlichen Parameter an Ihre Funktion, damit sie dort verarbeitet werden können.

Die anonyme Funktion kann für sehr grundlegende Dinge funktionieren, aber innerhalb eines Objekts, in dem Sie "this" verwenden müssen, gibt es keine Möglichkeit, es zum Laufen zu bringen. Jede anonyme Funktion ändert "dies" so, dass sie auf das Fenster zeigt, sodass Sie Ihre Objektreferenz verlieren.

Jiri Vetyska
quelle
24
Mit Traurigkeit in meinem Herzen muss ich informieren: Dies funktioniert im Internet Explorer nicht. : / Alle zusätzlichen Parameter werden als undefiniert angezeigt.
Amalgovinus
6
Ich benutze nurvar that = this; setTimeout( function() { that.foo(); }, 1000);
Ed Williams
2
Dies ist korrekt und in HTML5 angegeben. whatwg.org/specs/web-apps/current-work/multipage/…
Garrett
4
Dies ist genau die gleiche Antwort wie bei Fabio .
Dan Dascalescu
1
Laut developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout werden die Rückrufargumente für Internet Explorer nur in Versionen> = 10 unterstützt. Seien Sie vorsichtig, da auf vielen Websites ie8 und ie9 immer noch relevante Anteile erhalten.
Le0diaz
45

Dies ist eine sehr alte Frage mit einer bereits "richtigen" Antwort, aber ich dachte, ich würde einen anderen Ansatz erwähnen, den hier niemand erwähnt hat. Dies wird aus der ausgezeichneten Unterstrichbibliothek kopiert und eingefügt :

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

Sie können beliebig viele Argumente übergeben , wie Sie durch setTimeout genannt auf die Funktion möchten und als zusätzlichen Bonus (gut, in der Regel ein Bonus) der Wert der übergebenen Argumente an Ihre Funktion eingefroren sind , wenn Sie setTimeout rufen, so dass , wenn sie Wert zu ändern Irgendwann zwischen dem Aufruf von setTimeout () und dem Timeout, na ja ... das ist nicht mehr so ​​schrecklich frustrierend :)

Hier ist eine Geige, in der Sie sehen können, was ich meine.

David Meister
quelle
7
Diese Antwort funktioniert tatsächlich, aber Sie scheinen eine Bibliothek zu haben, die ich nicht habe. Hier ist die kleine Lösung, damit es funktioniert: Verwenden Sie anstelle von slot.call Array.prototype.slice.call (Argumente, 2)
Melanie
7
@ Melanie "eine Bibliothek"? Ich sagte in der Antwort, dass es die Unterstrichbibliothek ist - underscorejs.org . Aber ja, Array.prototype.slice ist aliasiert, um in diese Bibliothek zu schneiden, also müssen Sie das selbst tun, wenn Sie es nicht verwenden, guter Ort :)
David Meister
38

Ich bin kürzlich auf die einzigartige Situation gestoßen, eine setTimeoutin einer Schleife verwenden zu müssen . Wenn Sie dies verstehen, können Sie besser verstehen, wie Parameter übergeben werden setTimeout.

Methode 1

Verwenden Sie forEachund Object.keysgemäß Sukimas Vorschlag :

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

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

Ich empfehle diese Methode.

Methode 2

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

Methode 3

Oder wenn Sie nicht verwenden können , forEachoder bindverwenden Sie ein IIFE :

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

Methode 4

Wenn Sie sich jedoch nicht für IE <10 interessieren, können Sie Fabios Vorschlag verwenden :

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

Methode 5 (ES6)

Verwenden Sie eine Variable mit Blockbereich:

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

Obwohl ich immer noch empfehlen würde, Object.keysmit forEachin ES6 zu verwenden.

David Sherret
quelle
2
Hinweis: Funktioniert .bindnicht für IE8 und niedriger [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Am Ende habe ich Schiens Lösung verwendet: stackoverflow.com/a/21213723/1876899
cjspurgeon
1
Wenn Sie in einer Umgebung sind, die verwendet, binddann sind Sie auch in einer Umgebung, die Object.keysund bietet forEach. Sie können die for-Schleife verlieren und dabei einen "freien" Funktionsumfang (wie bei zwei Vögeln mit einer Klappe frei, nicht ressourcenfrei) erhalten.
Sukima
@ David Sherret falls Sie es noch nicht benutzt haben, schauen Sie sich auf jeden Fall die asyncBibliothek an ( github.com/caolan/async ). Wir verwenden es ausgiebig in Segeln und haben in den letzten 2 Jahren großartige Ergebnisse erzielt. Es stellt Verfahren in sowohl parallel als auch in Serie für asynchrone forEach, map, reduceusw.
mikermcneil
25

Hobblin hat dies bereits zu der Frage kommentiert, aber es sollte wirklich eine Antwort sein!

Die Verwendung Function.prototype.bind()ist der sauberste und flexibelste Weg, dies zu tun (mit dem zusätzlichen Vorteil, den thisKontext festlegen zu können ):

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

Weitere Informationen finden Sie unter diesen MDN-Links:
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

dain
quelle
Dieser Kontext kann mit dem ersten Argument von bindsetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano
@ GiuseppeGalano total, ich habe das in meiner Antwort erwähnt, aber es wird für dieses Beispiel nicht benötigt :)
Dain
Faszinierend, wie viel Glanz über Teilanwendungen mit bind. Es sorgt wirklich für lesbaren Code.
Sukima
bind () wird nur von IE9 + unterstützt, daher funktioniert dieser Ansatz nicht für <IE9
Sanjeev
@ Sanjeev Verwenden Sie ES5 Shim, damit es in älteren IE funktioniert: github.com/es-shims/es5-shim
Gregers
17

Einige Antworten sind richtig, aber verworren.

Ich beantworte dies 4 Jahre später erneut, weil ich immer noch auf übermäßig komplexen Code stoße, um genau diese Frage zu lösen. Es gibt eine elegante Lösung.

Übergeben Sie beim Aufrufen von setTimeout zunächst keinen String als ersten Parameter, da dadurch die langsame Funktion "eval" effektiv aufgerufen wird.

Wie übergeben wir einen Parameter an eine Timeout-Funktion? Durch Verwendung von Verschluss:

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

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

Einige haben vorgeschlagen, beim Aufrufen der Timeout-Funktion eine anonyme Funktion zu verwenden:

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

Die Syntax funktioniert. Zu dem Zeitpunkt, zu dem Settopic aufgerufen wird, dh 4 Sekunden später, ist das XHR-Objekt möglicherweise nicht mehr dasselbe. Daher ist es wichtig, die Variablen vorab zu binden .

Schien
quelle
1
+1 für eine lesbare Lösung, die sich geringfügig von meiner unterscheidet. Während Sie das setTimeout in der Settopic-Funktion haben, habe ich die fDelayed-Funktion (Ihr Settopic) in der setTimeout-Funktion.
Dominic
11

Meine Antwort:

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

Erläuterung:

Die erstellte anonyme Funktion gibt eine andere anonyme Funktion zurück. Diese Funktion hat Zugriff auf die ursprünglich übergebene Funktion topicId, sodass kein Fehler auftritt. Die erste anonyme Funktion wird sofort aufgerufen und übergeben topicId, sodass die registrierte Funktion mit einer Verzögerung zum topicIdZeitpunkt des Aufrufs über Schließungen Zugriff hat .

ODER

Dies konvertiert im Grunde zu:

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

EDIT: Ich habe die gleiche Antwort gesehen, also schau dir seine an. Aber ich habe seine Antwort nicht gestohlen! Ich habe nur vergessen zu schauen. Lesen Sie die Erklärung und prüfen Sie, ob es hilfreich ist, den Code zu verstehen.


quelle
Dies ist die beste Antwort. Viele dieser Lösungen werden das Timeout nicht einmal einhalten. Warum setzen Sie jedoch die erste anonyme Funktion in Klammern? Ich denke nicht, dass sie notwendig sind, um dies zu erreichen.
Robert Henderson
Dies ist die beste Antwort 👍, musste aber einen Klon durchführen, da sich auch topicIdder Wert im Timeout ändert, wenn Werte wie geändert werden. Ein Klon hat es behoben
Pariola
10

Ersetzen

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

mit

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

oder noch besser, ersetzen Sie den Zeichenfolgenausdruck durch eine anonyme Funktion

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

BEARBEITEN:

Brownstones Kommentar ist falsch. Dies funktioniert wie beabsichtigt, wie durch Ausführen in der Firebug-Konsole gezeigt wird

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

Beachten Sie, dass ich mit anderen einverstanden bin, dass Sie vermeiden sollten, eine Zeichenfolge zu übergeben, setTimeoutda dies eval()die Zeichenfolge aufruft und stattdessen eine Funktion übergibt .

Russ Cam
quelle
Dies funktioniert nicht, da das Ergebnis von postinsql (topicId) von setTimeout ausgeführt wird. Sie müssen es in eine Funktion wie bei der ersten Antwort einschließen oder einen Helfer wie Prototyps .curry () - setTimeout (postinsql.curry (topidId), 4000) verwenden.
Shuckster
2
@brownstone: Das ist falsch. Die Zeichenfolge wird ausgewertet, wenn das Timeout ausgelöst wird.
Meilen
9

Sie können den Parameter wie folgt an die Rückruffunktion setTimeout übergeben:

setTimeout (Funktion, Millisekunden, param1, param2, ...)

z.B.

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

function alertMsg(message) {
    alert(message)
}
Jatin Verma
quelle
1
Kann mir jemand sagen, warum diese Antwort nicht die bevorzugte ist? Dies ist meiner Meinung nach der einfachste Weg! So einfach wiesetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Mazhar Zandsalimi
1
Ja! Dies sollte die akzeptierte Antwort sein. Von MDN: developer.mozilla.org/en-US/docs/Web/API/…
Han
5

Ich weiß, dass diese Frage vor 10 Jahren gestellt wurde, aber wenn Sie bis hierher gescrollt haben, gehe ich davon aus, dass Sie immer noch vor einem Problem stehen. Die Lösung von Meder Omuraliev ist die einfachste und mag den meisten von uns helfen, aber für diejenigen, die keine Bindung haben möchten, hier ist sie:

  1. Verwenden Sie Param für setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Verwenden Sie den sofort aufgerufenen Funktionsausdruck (IIFE).
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Lösung für die Frage
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}
Alpesh Patil
quelle
4

Ich weiß, dass es alt ist, aber ich wollte meinen (bevorzugten) Geschmack hinzufügen.

Ich denke, ein ziemlich lesbarer Weg, dies zu erreichen, besteht darin, das topicIdan eine Funktion zu übergeben, die wiederum das Argument verwendet, um die Themen-ID intern zu referenzieren. Dieser Wert ändert sich auch dann nicht, wenn er topicIdkurz darauf von außen geändert wird.

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

oder kurz:

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

Die Antwort von David Meister scheint sich um Parameter zu kümmern, die sich unmittelbar nach dem Aufruf von setTimeout (), jedoch vor dem Aufruf der anonymen Funktion ändern können. Aber es ist zu umständlich und nicht sehr offensichtlich. Ich habe eine elegante Methode entdeckt, mit IIFE (sofort aufgerufener Funktionsausdruck) so ziemlich dasselbe zu tun.

Im folgenden Beispiel wird die currentListVariable an das IIFE übergeben, wodurch sie beim Schließen gespeichert wird, bis die verzögerte Funktion aufgerufen wird. Selbst wenn sich die Variable currentListunmittelbar nach dem angezeigten Code ändert, setInterval()wird die Variable das Richtige tun.

Ohne diese IIFE-Technik wird die setTimeout()Funktion definitiv für jedes h2Element im DOM aufgerufen , aber bei all diesen Aufrufen wird nur der Textwert des letzten h2 Elements angezeigt .

<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>
Gurjeet Singh
quelle
4

Wenn Sie eine Funktion als Rückruf mit bestimmten Parametern übergeben müssen, können Sie im Allgemeinen Funktionen höherer Ordnung verwenden. Dies ist ziemlich elegant mit ES6:

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

setTimeout(someFunction(params), 1000);

Oder wenn someFunctionist erste Bestellung:

setTimeout(() => someFunction(params), 1000); 
John Hartman
quelle
Dies ist sehr inkompatibel
user151496
Elegant in der Tat! Vielen Dank
Velojet
3

Beachten Sie, dass der Grund, warum topicId gemäß der Fehlermeldung "nicht definiert" wurde, darin besteht, dass es als lokale Variable vorhanden war, als setTimeout ausgeführt wurde, jedoch nicht, als der verzögerte Aufruf von postinsql erfolgte. Die variable Lebensdauer ist besonders wichtig, insbesondere wenn Sie versuchen, "dies" als Objektreferenz zu übergeben.

Ich habe gehört, dass Sie topicId als dritten Parameter an die Funktion setTimeout übergeben können. Es werden nicht viele Details angegeben, aber ich habe genug Informationen, damit es funktioniert, und es ist in Safari erfolgreich. Ich weiß allerdings nicht, was sie mit dem "Millisekundenfehler" meinen. Schau es dir hier an:

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

Billy
quelle
3

Wie habe ich diese Phase gelöst?

genau so :

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

setTimeout wartet auf einen Verweis auf eine Funktion, also habe ich ihn in einem Closure erstellt, der meine Daten interpretiert und eine Funktion mit einer guten Instanz meiner Daten zurückgibt!

Vielleicht können Sie diesen Teil verbessern:

_deepFunction(_deepData);

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

Ich habe es auf Chrome, Firefox und IE getestet und es funktioniert gut. Ich weiß nichts über die Leistung, aber ich brauchte es, um zu funktionieren.

ein Beispieltest:

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

Vielleicht können Sie die Signatur ändern, um sie komfortabler zu gestalten:

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

Und schließlich zur Beantwortung der ursprünglichen Frage:

 myNass_setTimeOut( postinsql, 4000, topicId );

Hoffe es kann helfen!

ps: sorry aber englisch es ist nicht meine muttersprache!

Anonymous0day
quelle
Dies ist im Vergleich zu anderen Antworten zu kompliziert.
Dan Dascalescu
3

Dies funktioniert in allen Browsern (IE ist ein seltsamer Ball)

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

Wenn Sie eine Variable als Parameter übergeben möchten, versuchen Sie dies

Wenn die Anforderung Funktion und Var als Parmas ist, versuchen Sie dies

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

Wenn die Anforderung nur Variablen als Parameter sind, versuchen Sie dies

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

Sie können dies mit ES5 und ES6 versuchen

verrückter Mann
quelle
2

Sie können die Standardfunktionalität von 'apply ()' wie folgt ausprobieren. Sie können mehr Argumente als Ihre Anforderung im Array übergeben

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

setTimeout ist Teil des von WHAT WG definierten DOM.

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

Die gewünschte Methode ist: -

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

Plant eine Zeitüberschreitung für die Ausführung des Handlers nach einer Zeitüberschreitung von Millisekunden. Alle Argumente werden direkt an den Handler weitergeleitet.

setTimeout(postinsql, 4000, topicId);

Anscheinend werden zusätzliche Argumente in IE10 unterstützt. Alternativ können Sie verwenden setTimeout(postinsql.bind(null, topicId), 4000);, das Übergeben zusätzlicher Argumente ist jedoch einfacher, und das ist vorzuziehen.

Historisches Faktoid: In Tagen von VBScript war in JScript der dritte Parameter von setTimeout die Sprache als Zeichenfolge, standardmäßig "JScript", jedoch mit der Option "VBScript". https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)

Garrett
quelle
0

@Jiri Vetyska danke für den Beitrag, aber in deinem Beispiel stimmt etwas nicht. Ich musste das schwebende Ziel (dies) an eine Zeitüberschreitungsfunktion übergeben und habe Ihren Ansatz ausprobiert. In IE9 getestet - funktioniert nicht. Ich habe auch einige Nachforschungen angestellt und es scheint, dass der dritte Parameter , wie hier gezeigt, die verwendete Skriptsprache ist. Keine Erwähnung über zusätzliche Parameter.

Also folgte ich der Antwort von @ meder und löste mein Problem mit diesem Code:

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

Hoffe, das ist nützlich für jemand anderen.

Vladislav
quelle
0

Da es im IE ein Problem mit dem dritten optonalen Parameter gibt und die Verwendung von Verschlüssen verhindert, dass wir die Variablen ändern (z. B. in einer Schleife) und dennoch das gewünschte Ergebnis erzielen, schlage ich die folgende Lösung vor.

Wir können versuchen, Rekursion wie folgt zu verwenden:

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

Wir müssen sicherstellen, dass nichts anderes diese Variablen ändert und dass wir eine ordnungsgemäße Rekursionsbedingung schreiben, um eine unendliche Rekursion zu vermeiden.

Vakhtang Tevdorashvili
quelle
0

// Dies sind drei sehr einfache und prägnante Antworten:

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');
Reich
quelle
0

Beantwortung der Frage aber durch eine einfache Additionsfunktion mit 2 Argumenten.

var x = 3, y = 4;

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

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

Sie müssen AnführungszeichensetTimeOut wie folgt aus Ihrem Funktionsaufruf entfernen :

setTimeout(postinsql(topicId),4000);
Ghanshyam Sharma
quelle
-1

Ich denke du willst:

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

quelle
1
Ich bin auf Fälle gestoßen, in denen dies einfach nicht funktioniert (was immer zu einem Fehler "Funktion nicht definiert" führt), aber die Verwendung der anonymen Funktion funktioniert. Was frustrierend ist, da jeder zu sagen scheint, dass die obige Syntax immer funktionieren sollte. (Könnte es sein, dass jQuery der Methode 'quote as string' irgendwie im Weg steht?)
DA.
6
Nehmen wir an, dass topicId eine Funktion ist ... oder ein Objekt. Das wird nicht funktionieren!
Serafeim
Wenn Sie mit dieser Methode wirklich fortfahren möchten, verwenden Sie sie JSON.stringifyfür reguläre Objekte und Arrays und verwenden Sie sie dann JSON.parseinnerhalb der Funktion. Das gesamte Verhalten geht jedoch verloren, wenn das Objekt über Methoden verfügt.
DarthCadeus
-2

// Dies sind drei sehr einfache und prägnante Antworten:

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');
user11385739
quelle