Bagaimana saya bisa meneruskan parameter ke callback setTimeout ()?

825

Saya memiliki beberapa kode JavaScript yang terlihat seperti:

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

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

Saya mendapatkan kesalahan yang topicIdtidak didefinisikan. Semuanya berfungsi sebelum saya menggunakan setTimeout()fungsi.

Saya ingin postinsql(topicId)fungsi saya dipanggil setelah beberapa waktu. Apa yang harus saya lakukan?

Zeeshan Rang
sumber
75
sakit sedikit mengomentari topik lama tapi saya hanya harus menawarkan versi ketiga (yang menurut saya jauh lebih bersih): setTimeout (postinsql.bind (null, topicId), 4000)
Hobblin
14
@ Hobblin: mengapa melukai catatan? Tidakkah hal itu akan lebih menyakiti orang lain ketika mendengar pertanyaan populer ini dan melihat gaya panggilan lama yang tidak digunakan?
Dan Dascalescu
2
semuanya jelas di sini: w3schools.com/jsref/met_win_settimeout.asp
Vladislav
@dbliss Saran saya telah disebutkan dalam beberapa jawaban dan ditambahkan sebagai jawaban di sini: stackoverflow.com/a/15620038/287130 Tapi saya senang saran saya dihargai;)
Hobblin
@Hobblin ah, terima kasih banyak sudah menunjukkannya. Saya telah menggulir mencari jawaban yang diposting oleh Anda dan melewatkannya.
dbliss

Jawaban:

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

Anda perlu memberi makan fungsi anonim sebagai parameter alih-alih sebuah string, metode yang terakhir bahkan tidak akan bekerja sesuai spesifikasi skrip ECMAS tetapi browser hanya lunak. Ini adalah solusi yang tepat, jangan pernah mengandalkan meneruskan string sebagai 'fungsi' saat menggunakan setTimeout()atau setInterval(), itu lebih lambat karena harus dievaluasi dan itu tidak benar.

MEMPERBARUI:

Seperti yang dikatakan Hobblin dalam komentarnya terhadap pertanyaan, sekarang Anda dapat meneruskan argumen ke fungsi di dalam setTimeout menggunakan Function.prototype.bind().

Contoh:

setTimeout(postinsql.bind(null, topicId), 4000);
meder omuraliev
sumber
30
window.setTimeoutadalah metode DOM, dan karenanya tidak ditentukan oleh spesifikasi skrip ECMAS. Melewati string selalu berfungsi di browser, dan merupakan standar de facto — pada kenyataannya, kemampuan untuk melewatkan objek fungsi ditambahkan kemudian, dengan JavaScript 1.2 — itu secara eksplisit merupakan bagian dari spesifikasi draft HTML5 ( whatwg.org/specs/web -apps / current-work / multipage / ... ). Namun, menggunakan string sebagai ganti objek fungsi umumnya dianggap gaya buruk karena pada dasarnya merupakan bentuk yang tertunda eval().
Miles
2
var temp = setTimeout (function () {postinsql (topicId);}, 4000); clearTimeout (temp); ??
Josh Mc
12
Apa yang akan terjadi jika topicId diubah setelah batas waktu ditetapkan, tetapi sebelum fungsinya dipanggil?
pilau
22
@ Pilau itulah masalah saya: jika variabel yang digunakan dalam fungsi anonim berubah sebelum batas waktu (seperti dalam untuk loop) maka juga akan berubah di dalam fungsi. Jadi, dalam contoh saya pengaturan 5 timeout yang berbeda dalam untuk loop benar-benar berakhir menggunakan variabel yang sama. Hati-hati saat menggunakan jawaban ini!
Cristian
10
@pilau menggunakan penutupan lain akan membantu topicId = 12; fungsi postinsql (topicId) {console.log (topicId); } function setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13;
Halis Yılboğa
727

Di browser modern, "setTimeout" menerima parameter ketiga yang dikirim sebagai parameter ke fungsi internal di akhir penghitung waktu.

Contoh:

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

Keterangan lebih lanjut:

Fabio Phms
sumber
56
Saya tidak yakin mengapa jawaban ini tidak dipilih sebagai yang terbaik. Menggunakan fungsi anonim berfungsi, tentu saja, tetapi jika Anda bisa dengan mudah memberikan parameter ketiga ke panggilan fungsi setTimeout yang asli ... mengapa tidak?
Kris Schouw
54
Karena tidak berfungsi di versi IE masih sangat banyak di alam liar.
Aaron
4
Jawaban ini benar-benar membuat saya dapat melewati objek acara, metode lainnya tidak. Saya sudah memiliki fungsi anonim.
Glenn Plas
27
Jawaban yang jauh lebih baik. Jika Anda memiliki kode yang mengubah parameter Anda antara panggilan "setTimeout" dan eksekusi aktual dari fungsi anonim - fungsi anonim akan menerima nilai yang dimodifikasi, bukan seperti pada saat panggilan setTimeout. misalnya: untuk (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } ini akan mencatat "100" a 100 kali (diuji pada FF). Jawaban saat ini membantu menghindari hal ini.
root
1
Menurut developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout , argumen panggilan balik untuk Internet Explorer hanya didukung dalam versi> = 10, hati-hati karena di banyak situs ie8 dan ie9 masih mendapatkan bagian yang relevan.
le0diaz
154

Setelah melakukan beberapa penelitian dan pengujian, satu-satunya implementasi yang benar adalah:

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

setTimeout akan meneruskan semua parameter tambahan ke fungsi Anda sehingga dapat diproses di sana.

Fungsi anonim dapat bekerja untuk hal-hal yang sangat mendasar, tetapi dalam contoh objek di mana Anda harus menggunakan "ini", tidak ada cara untuk membuatnya berfungsi. Setiap fungsi anonim akan mengubah "ini" untuk menunjuk ke jendela, sehingga Anda akan kehilangan referensi objek Anda.

Jiri Vetyska
sumber
24
Dengan kesedihan di hati saya bahwa saya harus menginformasikan: ini tidak bekerja di internet explorer : / Semua params tambahan datang sebagai tidak terdefinisi.
Amalgovinus
6
Saya hanya menggunakanvar that = this; setTimeout( function() { that.foo(); }, 1000);
Ed Williams
2
Ini benar, dan itu ditentukan dalam HTML5. whatwg.org/specs/web-apps/current-work/multipage/…
Garrett
4
Ini adalah jawaban yang persis sama dengan jawaban Fabio .
Dan Dascalescu
1
Menurut developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout , argumen panggilan balik untuk Internet Explorer hanya didukung dalam versi> = 10, hati-hati karena di banyak situs ie8 dan ie9 masih mendapatkan bagian yang relevan.
le0diaz
45

Ini adalah pertanyaan yang sangat lama dengan jawaban yang sudah "benar" tetapi saya pikir saya akan menyebutkan pendekatan lain yang tidak ada yang disebutkan di sini. Ini disalin dan ditempel dari perpustakaan garis bawah yang sangat baik :

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

Anda bisa memberikan argumen sebanyak yang Anda inginkan ke fungsi yang dipanggil oleh setTimeout dan sebagai bonus tambahan (well, biasanya bonus) nilai argumen yang dilewatkan ke fungsi Anda dibekukan saat Anda memanggil setTimeout, jadi jika mereka mengubah nilai di beberapa titik antara ketika setTimeout () dipanggil dan ketika waktu habis, yah ... itu tidak terlalu membuat frustrasi lagi :)

Ini biola di mana Anda bisa melihat apa yang saya maksud.

David Meister
sumber
7
Jawaban itu sebenarnya berfungsi tetapi Anda tampaknya memiliki beberapa perpustakaan yang tidak saya miliki. Berikut ini sedikit perbaikan agar berhasil: alih-alih slice.call, gunakan Array.prototype.slice.call (argumen, 2)
Melanie
7
@Melanie "perpustakaan"? Saya mengatakan dalam jawaban bahwa itu adalah perpustakaan garis bawah - underscorejs.org . Tapi ya, Array.prototype.slice alias mengiris di dalam perpustakaan itu, jadi Anda harus melakukannya sendiri jika Anda tidak menggunakannya, good spot :)
David Meister
38

Saya baru-baru ini menemukan situasi unik yang perlu digunakan setTimeoutdalam satu lingkaran . Memahami hal ini dapat membantu Anda memahami cara meneruskan parameter setTimeout.

Metode 1

Gunakan forEachdan Object.keys, sesuai saran Sukima :

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

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

Saya merekomendasikan metode ini.

Metode 2

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

Metode 3

Atau jika Anda tidak dapat menggunakan forEachatau bind, gunakan IIFE :

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

Metode 4

Tetapi jika Anda tidak peduli tentang IE <10, maka Anda dapat menggunakan saran Fabio :

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

Metode 5 (ES6)

Gunakan variabel scoped blok:

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

Meskipun saya masih akan merekomendasikan menggunakan Object.keysdengan forEachES6.

David Sherret
sumber
2
Catatan: .bindtidak akan berfungsi untuk IE8 dan di bawah ini [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Saya akhirnya menggunakan solusi Schien: stackoverflow.com/a/21213723/1876899
cjspurgeon
1
Jika Anda berada di lingkungan yang menggunakan bindmaka Anda juga berada dalam lingkungan yang menawarkan Object.keysdan forEach. Anda dapat kehilangan for for loop dan mendapatkan lingkup fungsi "bebas" (seperti pada dua burung dengan satu batu gratis bukan bebas sumber daya) dalam proses.
Sukima
@ David Sherret jika Anda belum pernah menggunakannya sebelumnya, pasti periksa asyncperpustakaan ( github.com/caolan/async ). Kami menggunakannya secara luas dalam Sails dan memiliki hasil yang bagus selama 2 tahun terakhir. Ini menyediakan metode di kedua paralel dan seri untuk asynchronous forEach, map, reduce, dll
mikermcneil
25

Hobblin sudah mengomentari ini pada pertanyaan, tetapi itu harus benar-benar menjadi jawaban!

Menggunakan Function.prototype.bind()adalah cara paling bersih dan paling fleksibel untuk melakukan ini (dengan bonus tambahan untuk dapat mengatur thiskonteks):

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

Untuk informasi lebih lanjut, lihat tautan MDN ini:
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

lelah
sumber
konteks ini dapat diteruskan dengan argumen pertama dari bindsetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano
@GiuseppeGalano benar-benar, saya menyebutkan bahwa dalam jawaban saya, tapi itu tidak diperlukan untuk contoh ini :)
dain
Menarik berapa banyak aplikasi gloss over sebagian menggunakan bind. Itu benar-benar membuat beberapa kode dapat dibaca.
Sukima
bind () hanya didukung dari IE9 +, jadi pendekatan ini tidak akan berfungsi untuk <IE9
Sanjeev
@Sanjeev Gunakan ES5 shim untuk membuatnya bekerja di IE yang lebih lama: github.com/es-shims/es5-shim
gregers
17

Beberapa jawaban benar tetapi berbelit-belit.

Saya menjawab ini lagi, 4 tahun kemudian, karena saya masih mengalami kode yang terlalu rumit untuk menyelesaikan pertanyaan ini. ADA solusi yang elegan.

Pertama-tama, jangan berikan string sebagai parameter pertama saat memanggil setTimeout karena secara efektif memanggil panggilan ke fungsi "eval" yang lambat.

Jadi, bagaimana kita mengirimkan parameter ke fungsi batas waktu? Dengan menggunakan penutupan:

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

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

Beberapa menyarankan menggunakan fungsi anonim saat memanggil fungsi batas waktu:

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

Sintaksnya berhasil. Tetapi pada saat settopic dipanggil, yaitu 4 detik kemudian, objek XHR mungkin tidak sama. Karena itu penting untuk melakukan pre-bind variabel .

Schien
sumber
1
+1 untuk solusi yang dapat dibaca, sedikit berbeda dengan saya. Meskipun Anda memiliki setTimeout di dalam fungsi settopic, saya memiliki fungsi fDelayed (settopic Anda) di dalam fungsi setTimeout.
Dominic
11

Jawabanku:

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

Penjelasan:

Fungsi anonim yang dibuat mengembalikan fungsi anonim lain. Fungsi ini memiliki akses ke yang semula disahkan topicId, sehingga tidak akan membuat kesalahan. Fungsi anonim pertama segera dipanggil, lewat topicId, sehingga fungsi terdaftar dengan penundaan memiliki akses topicIdpada saat menelepon, melalui penutupan.

ATAU

Ini pada dasarnya dikonversi ke:

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

EDIT: Saya melihat jawaban yang sama, jadi lihatlah jawabannya. Tapi aku tidak mencuri jawabannya! Saya hanya lupa melihat. Baca penjelasannya dan lihat apakah ada baiknya memahami kodenya.


sumber
Ini jawaban terbaik. Banyak solusi ini bahkan tidak akan menghormati batas waktu. Namun, mengapa Anda membungkus fungsi anonim pertama dalam tanda kurung? Saya pikir mereka tidak perlu melakukan ini.
Robert Henderson
ini adalah jawaban terbaik 👍, tetapi harus melakukan kloning karena ketika nilai suka topicIddiubah nilai dalam batas waktu juga berubah. Sebuah klon memperbaikinya
pariola
10

Menggantikan

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

dengan

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

atau lebih baik lagi, ganti ekspresi string dengan fungsi anonim

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

EDIT:

Komentar Brownstone salah, ini akan berfungsi sebagaimana dimaksud, seperti yang ditunjukkan dengan menjalankan ini di konsol Firebug

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

Perhatikan bahwa saya setuju dengan orang lain bahwa Anda harus menghindari meneruskan string setTimeoutkarena ini akan memanggil eval()string dan alih-alih meneruskan fungsi.

Russ Cam
sumber
Ini tidak akan berfungsi karena hasil postinsql (topicId) akan dieksekusi oleh setTimeout. Anda perlu membungkusnya dalam suatu fungsi seperti dengan jawaban pertama, atau menggunakan pembantu seperti .curry () Prototype -) setTimeout (postinsql.curry (topidId), 4000);
shuckster
2
@ brownstone: Itu tidak benar. Tali akan dievaluasi saat batas waktu habis.
Miles
9

Anda dapat meneruskan parameter ke fungsi panggilan balik setTimeout sebagai:

setTimeout (fungsi, milidetik, param1, param2, ...)

misalnya.

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

function alertMsg(message) {
    alert(message)
}
Jatin Verma
sumber
1
Adakah yang bisa memberi tahu saya mengapa jawaban ini bukan yang disukai? ini adalah cara paling sederhana menurut saya! SesederhanasetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Mazhar Zandsalimi
1
Ya! Ini harus menjadi jawaban yang diterima. Dari MDN: developer.mozilla.org/en-US/docs/Web/API/…
Han
5

Saya tahu sudah 10 tahun sejak pertanyaan ini diajukan, tetapi tetap saja, jika Anda telah menggulir sampai di sini, saya menganggap Anda masih menghadapi beberapa masalah. Solusi oleh Meder Omuraliev adalah yang paling sederhana dan dapat membantu sebagian besar dari kita tetapi bagi mereka yang tidak ingin memiliki ikatan apa pun, ini dia:

  1. Gunakan Param untuk setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Gunakan Ekspresi Fungsi Segera Diminta (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Solusi untuk pertanyaan itu
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

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

Saya tahu ini sudah tua tetapi saya ingin menambahkan rasa (pilihan) saya pada ini.

Saya pikir cara yang cukup mudah dibaca untuk mencapai ini adalah dengan meneruskan topicIdke fungsi, yang pada gilirannya menggunakan argumen untuk referensi ID topik secara internal. Nilai ini tidak akan berubah bahkan jika topicIddi luar akan diubah segera setelahnya.

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

atau pendek:

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

Jawaban oleh David Meister tampaknya menangani parameter yang dapat berubah segera setelah panggilan ke setTimeout () tetapi sebelum fungsi anonim dipanggil. Tapi itu terlalu rumit dan tidak terlalu jelas. Saya menemukan cara yang elegan untuk melakukan hal yang hampir sama dengan menggunakan IIFE (ekspresi fungsi langsung inviked).

Dalam contoh di bawah ini, currentListvariabel dilewatkan ke IIFE, yang menyimpannya dalam penutupannya, sampai fungsi tertunda dipanggil. Bahkan jika variabel currentListberubah segera setelah kode ditampilkan, setInterval()akan melakukan hal yang benar.

Tanpa teknik IIFE ini, setTimeout()fungsi pasti akan dipanggil untuk setiap h2elemen di DOM, tetapi semua panggilan itu hanya akan melihat nilai teks dari elemen terakhir h2 .

<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
sumber
4

Secara umum, jika Anda harus meneruskan fungsi sebagai panggilan balik dengan parameter tertentu, Anda dapat menggunakan fungsi urutan yang lebih tinggi. Ini cukup elegan dengan ES6:

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

setTimeout(someFunction(params), 1000);

Atau jika someFunctionurutan pertama:

setTimeout(() => someFunction(params), 1000); 
John Hartman
sumber
ini sangat tidak kompatibel
user151496
Memang elegan! Terima kasih
Velojet
3

Perhatikan bahwa alasan topicId "tidak didefinisikan" per pesan kesalahan adalah bahwa itu ada sebagai variabel lokal ketika setTimeout dieksekusi, tetapi tidak ketika panggilan tertunda ke postinsql terjadi. Variabel seumur hidup sangat penting untuk diperhatikan, terutama ketika mencoba sesuatu seperti melewatkan "ini" sebagai referensi objek.

Saya mendengar bahwa Anda dapat meneruskan topicId sebagai parameter ketiga ke fungsi setTimeout. Tidak banyak detail diberikan tetapi saya mendapat informasi yang cukup untuk membuatnya berfungsi, dan itu berhasil di Safari. Saya tidak tahu apa artinya tentang "kesalahan milidetik". Lihat disini:

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

billy
sumber
3

Bagaimana saya menyelesaikan tahap ini?

seperti itu :

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

setTimeout menunggu referensi ke suatu fungsi, jadi saya membuatnya dalam penutup, yang menginterpretasikan data saya dan mengembalikan fungsi dengan contoh data saya yang bagus!

Mungkin Anda bisa memperbaiki bagian ini:

_deepFunction(_deepData);

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

Saya mengujinya pada chrome, firefox dan IE dan itu berjalan dengan baik, saya tidak tahu tentang kinerja tetapi saya membutuhkannya untuk bisa bekerja.

tes sampel:

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

Mungkin Anda dapat mengubah tanda tangan agar lebih patuh:

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

Dan akhirnya menjawab pertanyaan asli:

 myNass_setTimeOut( postinsql, 4000, topicId );

Semoga bisa membantu!

ps: maaf tapi bahasa Inggris itu bukan bahasa ibu saya!

Anonim0hari
sumber
Ini terlalu rumit, dibandingkan dengan jawaban lain.
Dan Dascalescu
3

ini bekerja di semua browser (IE adalah sebuah ganjil)

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

jika Anda ingin meneruskan variabel sebagai param mari kita coba ini

jika persyaratan adalah fungsi dan var sebagai parmas maka coba ini

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

jika persyaratan hanya variabel sebagai params maka coba ini

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

Anda dapat mencoba ini dengan ES5 dan ES6

orang gila
sumber
2

Anda dapat mencoba fungsionalitas default dari 'apply ()' sesuatu seperti ini, Anda dapat memberikan lebih banyak argumen sebagai kebutuhan Anda dalam array

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

setTimeout adalah bagian dari DOM yang ditentukan oleh WHAT WG.

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

Metode yang Anda inginkan adalah: -

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

Jadwalkan batas waktu untuk menjalankan handler setelah batas waktu milidetik. Setiap argumen diteruskan langsung ke pawang.

setTimeout(postinsql, 4000, topicId);

Rupanya, argumen tambahan didukung di IE10. Atau, Anda dapat menggunakan setTimeout(postinsql.bind(null, topicId), 4000);, namun memberikan argumen tambahan lebih sederhana, dan itu lebih disukai.

Fakta historis: Dalam hari-hari VBScript, dalam JScript, parameter ketiga setTimeout adalah bahasa, sebagai string, default ke "JScript" tetapi dengan opsi untuk menggunakan "VBScript". https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)

Garrett
sumber
0

@Jiri Vetyska terima kasih atas kirimannya, tetapi ada sesuatu yang salah dalam contoh Anda. Saya perlu melewati target yang melayang-layang (ini) ke fungsi time-out dan saya mencoba pendekatan Anda. Diuji dalam IE9 - tidak bekerja. Saya juga melakukan riset dan tampaknya seperti ditunjukkan di sini parameter ketiga adalah bahasa skrip yang digunakan. Tidak disebutkan tentang parameter tambahan.

Jadi, saya mengikuti jawaban @ meder dan menyelesaikan masalah saya dengan kode ini:

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

Semoga ini bermanfaat bagi orang lain.

Vladislav
sumber
0

Karena ada masalah dengan parameter optonal ketiga di IE dan menggunakan penutupan mencegah kita dari mengubah variabel (dalam satu lingkaran misalnya) dan masih mencapai hasil yang diinginkan, saya menyarankan solusi berikut.

Kita dapat mencoba menggunakan rekursi seperti ini:

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

Kita perlu memastikan bahwa tidak ada lagi yang mengubah variabel-variabel ini dan bahwa kita menulis kondisi rekursi yang tepat untuk menghindari rekursi tak terbatas.

Vakhtang Tevdorashvili
sumber
0

// Ini adalah tiga jawaban yang sangat sederhana dan ringkas:

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');
Kaya
sumber
0

Menjawab pertanyaan tetapi dengan fungsi penambahan sederhana dengan 2 argumen.

var x = 3, y = 4;

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

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

Anda harus menghapus tanda kutip dari setTimeOutpanggilan fungsi Anda seperti ini:

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

Saya pikir Anda ingin:

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

sumber
1
Saya telah mengalami contoh di mana itu tidak berfungsi (selalu menghasilkan kesalahan 'fungsi tidak didefinisikan') tetapi menggunakan fungsi anonim tidak berfungsi. Yang membuat frustrasi mengingat bahwa semua orang tampaknya mengatakan sintaks di atas harus selalu bekerja. (mungkinkah jQuery itu menghalangi metode 'quote as string'?)
DA.
6
Mari kita anggap bahwa topicId adalah fungsi ... Atau objek. Ini tidak akan berhasil!
Serafeim
Jika Anda benar-benar ingin melanjutkan dengan metode ini, gunakan JSON.stringifyuntuk objek dan array biasa, lalu gunakan JSON.parsedi dalam fungsi. Namun, semua perilaku akan hilang jika objek memiliki metode.
DarthCadeus
-2

// Ini adalah tiga jawaban yang sangat sederhana dan ringkas:

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');
pengguna11385739
sumber