मैं एक सेटटाइमआउट () कॉलबैक के लिए एक पैरामीटर कैसे पारित कर सकता हूं?


825

मेरा कुछ जावास्क्रिप्ट कोड है जो दिखता है:

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

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

मुझे एक त्रुटि मिलती है जो topicIdपरिभाषित नहीं है मैं setTimeout()फ़ंक्शन का उपयोग करने से पहले सब कुछ काम कर रहा था ।

मैं चाहता हूं कि postinsql(topicId)कुछ समय बाद मेरा फंक्शन बुलाया जाए। मुझे क्या करना चाहिए?


75
यह इस तरह के एक पुराने विषय पर टिप्पणी करने में थोड़ा कष्ट देता है, लेकिन मुझे सिर्फ एक तीसरा संस्करण प्रस्तुत करना है (जो मेरी राय में बहुत अधिक स्वच्छ है): setTimeout (postinsql.bind (null, topicId), 4000)
हॉबर्स

14
@ हॉब्लिन: रिकॉर्ड को सीधे सेट करने के लिए क्यों चोट लगी होगी? क्या इस लोकप्रिय प्रश्न पर उतरने और पुरानी, ​​असंतुष्ट कॉल शैली को देखने के लिए दूसरों को चोट नहीं पहुंचेगी?
डैन डैस्केल्स्कु

2
यहाँ सब स्पष्ट है: w3schools.com/jsref/met_win_settimeout.asp
व्लादिस्लाव

@dbliss मेरे सुझाव का पहले ही कई उत्तरों में उल्लेख किया जा चुका है और यहाँ एक उत्तर के रूप में जोड़ा गया है: stackoverflow.com/a/15620038/287130 लेकिन मुझे खुशी है कि मेरा सुझाव सराहा गया है;)
होब्बलिन

@ हबलिन आह, इस बात की ओर इशारा करने के लिए बहुत धन्यवाद। मैंने आपके द्वारा पोस्ट किए गए उत्तर की तलाश में स्क्रॉल किया था और वह चूक गया था।
dbliss

जवाबों:


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

आपको एक स्ट्रिंग के बजाय एक पैरामीटर के रूप में एक अनाम फ़ंक्शन खिलाने की आवश्यकता है, बाद वाली विधि को ECMAScript विनिर्देश के अनुसार भी काम नहीं करना चाहिए, लेकिन ब्राउज़र बस उदार हैं। यह उचित समाधान है, कभी भी एक स्ट्रिंग को 'फ़ंक्शन' के रूप में उपयोग करने पर निर्भर न करें setTimeout()या उपयोग करते समय setInterval(), यह धीमा है क्योंकि इसका मूल्यांकन किया जाना है और यह सही नहीं है।

अपडेट करें:

जैसा कि हॉब्लिन ने अपनी टिप्पणी में कहा था , अब आप सेटटाइमआउट का उपयोग करके फ़ंक्शन में तर्क पास कर सकते हैं Function.prototype.bind()

उदाहरण:

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

30
window.setTimeoutएक DOM विधि है, और जैसा कि ECMAScript विनिर्देश द्वारा परिभाषित नहीं है। स्ट्रिंग पास करना हमेशा ब्राउज़रों में काम करता है, और वास्तव में एक मानक मानक है - वास्तव में, फ़ंक्शन ऑब्जेक्ट को पास करने की क्षमता बाद में जावास्क्रिप्ट 1.2 के साथ जोड़ा गया था - यह स्पष्ट रूप से HTML5 ड्राफ्ट कल्पना ( whatwg.org/specs-web ) का हिस्सा है -apps / वर्तमान काम / गुणा /… )। हालांकि, एक फ़ंक्शन ऑब्जेक्ट के बजाय एक स्ट्रिंग का उपयोग करना आमतौर पर खराब शैली माना जाता है क्योंकि यह अनिवार्य रूप से देरी का एक रूप है eval()
मील्स

2
var अस्थायी = setTimeout (फ़ंक्शन () {postinsql (topicId);}, 4000); clearTimeout (अस्थायी); ??
जोश मैक

12
यदि टाइमआउट सेट होने के बाद विषय बदल जाता है, लेकिन फ़ंक्शन को कॉल करने से पहले क्या होगा?
पिलाउ

22
@ पिलाऊ यही मेरी समस्या है: यदि अनाम फ़ंक्शन में उपयोग किए जाने वाले चर टाइमआउट से पहले बदलते हैं (जैसे कि लूप के लिए) तो यह फ़ंक्शन के अंदर भी बदल जाएगा। इसलिए मेरे उदाहरण में एक लूप में 5 अलग-अलग टाइमआउट की स्थापना वास्तव में एक ही चर का उपयोग करके समाप्त हुई। इस उत्तर का उपयोग करते समय सावधान रहें!
क्रिस्टियन

10
@ पिलाऊ एक और बंद का उपयोग करने में मदद करेगा विषय = 12; function postinsql (topicId) {कंसोल.लॉग (topicId); } function setTimeOutWithClosure (topicId) {setTimeout (फ़ंक्शन () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13;
हालिस येलाबोआ

727

आधुनिक ब्राउज़रों में, "सेटटाइमआउट" एक तीसरा पैरामीटर प्राप्त करता है जिसे टाइमर के अंत में आंतरिक फ़ंक्शन के पैरामीटर के रूप में भेजा जाता है।

उदाहरण:

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

अधिक जानकारी:


56
मुझे यकीन नहीं है कि इस उत्तर को सर्वश्रेष्ठ के रूप में क्यों नहीं चुना गया। अनाम फ़ंक्शन का उपयोग करना, निश्चित रूप से, लेकिन अगर आप मूल पैरामीटर सेट टाइमआउट फ़ंक्शन कॉल में तीसरा पैरामीटर पास कर सकते हैं ... तो क्यों नहीं?
क्रिस शॉ

54
क्योंकि यह IE के संस्करणों में अभी भी बहुत जंगली में काम नहीं करता है।
एरॉन

4
इस जवाब ने मुझे वास्तव में एक ईवेंट ऑब्जेक्ट पास करने में सक्षम बना दिया, अन्य तरीके नहीं थे। मेरा पहले से ही एक अनाम फ़ंक्शन था।
ग्लेन प्लास

27
बेहतर जवाब से। यदि आपके पास कोड है जो "setTimeout" कॉल और अनाम फ़ंक्शन के वास्तविक निष्पादन के बीच आपके पैरामीटर को संशोधित करता है - अनाम फ़ंक्शन को संशोधित मूल्य प्राप्त होगा, न कि यह सेटटाइमआउट कॉल के समय था। उदाहरण के लिए: (var i = 0; मैं <100; i ++) {setTimeout (फ़ंक्शन () (कंसोल)। राइट (i);}, 0); } यह "100" 100 बार (एफएफ पर परीक्षण) लॉग करेगा। वर्तमान उत्तर इससे बचने में मदद करता है।
रूट

1
के अनुसार developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout इंटरनेट एक्सप्लोरर के लिए कॉलबैक तर्क केवल संस्करण> = 10 में समर्थित है, IE8 कई साइटों के रूप में सावधान हो सकता है और IE9 अभी भी कुछ प्रासंगिक हिस्सा मिलता है।
le0diaz

154

कुछ शोध और परीक्षण करने के बाद, केवल सही कार्यान्वयन है:

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

setTimeout आपके फ़ंक्शन के लिए सभी अतिरिक्त पैरामीटर पास करेगा ताकि उन्हें वहां संसाधित किया जा सके।

अनाम फ़ंक्शन बहुत ही मूल सामान के लिए काम कर सकता है, लेकिन एक वस्तु के उदाहरण के भीतर जहां आपको "इस" का उपयोग करना है, यह काम करने का कोई तरीका नहीं है। कोई भी अनाम फ़ंक्शन विंडो में इंगित करने के लिए "यह" बदल देगा, इसलिए आप अपना ऑब्जेक्ट संदर्भ खो देंगे।


24
यह मेरे दिल में दुख के साथ है कि मुझे सूचित करना चाहिए: यह इंटरनेट एक्सप्लोरर में काम नहीं करता है। : / सभी अतिरिक्त परिमाण अपरिभाषित के रूप में आते हैं।
अमलगोविनस

6
मैं अभी उपयोग करता हूंvar that = this; setTimeout( function() { that.foo(); }, 1000);
एड विलियम्स

2
यह सही है, और यह HTML5 में निर्दिष्ट है। whatwg.org/specs/web-apps/current-work/multipage/…
गैरेट

4
यह बिल्कुल वैसा ही जवाब है जैसा फैबियो का है
डेन डैस्कलेस्क्यू

1
के अनुसार developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout इंटरनेट एक्सप्लोरर के लिए कॉलबैक तर्क केवल संस्करण> = 10 में समर्थित है, IE8 कई साइटों के रूप में सावधान हो सकता है और IE9 अभी भी कुछ प्रासंगिक हिस्सा मिलता है।
le0diaz

45

यह पहले से ही "सही" उत्तर के साथ एक बहुत पुराना सवाल है, लेकिन मैंने सोचा कि मैं एक और दृष्टिकोण का उल्लेख करूंगा जिसका उल्लेख यहां किसी ने नहीं किया है। यह उत्कृष्ट अंडरस्कोर लाइब्रेरी से कॉपी और पेस्ट किया गया है :

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

आप सेट टाइमआउट द्वारा कहे गए फ़ंक्शन के अनुसार जितने चाहें उतने तर्क पारित कर सकते हैं और एक अतिरिक्त बोनस के रूप में (अच्छी तरह से, आमतौर पर एक बोनस) आपके फ़ंक्शन को दिए गए तर्कों का मूल्य सेटटाइमआउट कहते समय जमे हुए हैं, इसलिए यदि वे मान बदलते हैं जब सेटटाइमआउट () कहा जाता है और जब यह समय समाप्त होता है, तब के बीच कुछ बिंदु पर, अच्छी तरह से ... यह अब छिपी निराशा से ठीक नहीं है :)

यहाँ एक फील है जहाँ आप देख सकते हैं कि मेरा क्या मतलब है।


7
यह जवाब वास्तव में काम करता है, लेकिन आपको लगता है कि मुझे कुछ पुस्तकालय नहीं है। यहाँ यह काम करने के लिए थोड़ा ठीक है: slice.call के बजाय, Array.prototype.slice.call (तर्क, 2) का उपयोग करें
Melanie

7
@ मेलानी "कुछ पुस्तकालय"? मैंने जवाब में कहा कि यह अंडरस्कोर लाइब्रेरी है - underscorejs.org । लेकिन हाँ, Array.prototype.slice को उस लाइब्रेरी के अंदर स्लाइस करने के लिए अलियास किया जाता है, इसलिए आपको यह करना होगा कि यदि आप इसका उपयोग नहीं कर रहे हैं, तो यह अच्छा है :)
David Meister

38

मैं हाल ही setTimeoutमें एक लूप में उपयोग करने की आवश्यकता की अनूठी स्थिति में आया था । इसे समझने से आपको यह समझने में मदद मिल सकती है कि मापदंडों को कैसे पास किया जाए setTimeout

विधि 1

का प्रयोग करें forEachऔर Object.keys, Sukima के अनुसार सुझाव :

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

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

मैं इस विधि का सुझाव देता हूं।

विधि 2

उपयोग करें 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/

विधि 3

या यदि आप उपयोग नहीं कर सकते हैं forEachया bind, एक IIFE का उपयोग करें :

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

विधि 4

लेकिन अगर आपको IE <10 की परवाह नहीं है, तो आप फैबियो के सुझाव का उपयोग कर सकते हैं :

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

विधि 5 (ES6)

ब्लॉक स्कॉप्ड वैरिएबल का उपयोग करें:

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

हालांकि मैं अभी भी ES6 में उपयोग Object.keysकरने की सलाह forEachदूंगा।


2
नोट: .bindIE8 और उससे नीचे के लिए काम नहीं करेगा [Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]। मैंने शिएन के समाधान का उपयोग करके समाप्त कर दिया: stackoverflow.com/a/21213723/1876899
cjspurgeon

1
यदि आपका उपयोग करने वाले वातावरण में है bindतो आपका भी ऐसे वातावरण में जो प्रदान करता है Object.keysऔर forEach। आप लूप के लिए ढीले हो सकते हैं और प्रक्रिया में "नि: शुल्क" (दो पत्थरों के साथ एक पत्थर से मुक्त नहीं संसाधन मुक्त) फ़ंक्शन स्कोप प्राप्त कर सकते हैं।
सुकिमा

@ डेविड शेरेट यदि आपने पहले इसका उपयोग नहीं किया है, तो asyncलाइब्रेरी ( github.com/caolan/async ) को जरूर देखें । हम इसका बड़े पैमाने पर सेल में उपयोग करते हैं और पिछले 2 वर्षों से इसके शानदार परिणाम हैं। यह अतुल्यकालिक forEach, mapऔर reduce, आदि के लिए समानांतर और श्रृंखला में दोनों तरीके प्रदान करता है
mikermcneil

25

हॉब्लिन ने पहले ही इस सवाल पर टिप्पणी की, लेकिन यह वास्तव में एक जवाब होना चाहिए!

इसका उपयोग करना Function.prototype.bind()सबसे साफ और सबसे लचीला तरीका है ( thisसंदर्भ सेट करने में सक्षम होने के अतिरिक्त बोनस के साथ ):

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

अधिक जानकारी के लिए ये MDN लिंक देखें:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041 https://developer.mozilla.org/en/docs/JocsScript/Reference/Global_Objects/Function / बाँध # With_setTimeout


इस संदर्भ को बाँध के पहले तर्क के साथ पारित किया जा सकता हैsetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano

@GiuseppeGalano पूरी तरह से, मैंने अपने उत्तर में उल्लेख किया है, लेकिन इस उदाहरण के लिए इसकी आवश्यकता नहीं है :)
dain

का उपयोग करते हुए आंशिक अनुप्रयोगों पर कितने चमक bind। यह वास्तव में कुछ पठनीय कोड के लिए बनाता है।
सुकिमा

bind () केवल IE9 + से समर्थित है, इसलिए यह दृष्टिकोण <IE9 के लिए काम नहीं करेगा
संजीव


17

कुछ उत्तर सही हैं लेकिन दृढ़ हैं।

मैं 4 साल बाद फिर से इसका जवाब दे रहा हूं, क्योंकि मैं अभी भी इस प्रश्न को हल करने के लिए अत्यधिक जटिल कोड में चलता हूं। वहाँ एक सुंदर समाधान है।

सबसे पहले, सेटटाइमआउट करते समय पहले पैरामीटर के रूप में एक स्ट्रिंग में पास न करें क्योंकि यह प्रभावी रूप से धीमी "eval" फ़ंक्शन के लिए कॉल को आमंत्रित करता है।

तो हम टाइमआउट फ़ंक्शन के पैरामीटर में कैसे गुजरते हैं? बंद का उपयोग करके:

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

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

कुछ लोगों ने टाइमआउट फ़ंक्शन को कॉल करते समय अनाम फ़ंक्शन का उपयोग करने का सुझाव दिया है:

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

वाक्य रचना काम करती है। लेकिन तब तक सेटलमेंट कहा जाता है, यानी 4 सेकंड बाद, XHR ऑब्जेक्ट समान नहीं हो सकता है। इसलिए चर को पूर्व-बाँधना महत्वपूर्ण है ।


1
एक पठनीय समाधान के लिए +1, खदान से थोड़ा अलग। जबकि आपके पास सेटटॉप फ़ंक्शन के अंदर सेटटाइमआउट है, मेरे पास सेटटाइम फ़ंक्शन के अंदर fDelayed (आपका सेटटॉपिक) फ़ंक्शन है।
डोमिनिक

11

मेरा जवाब:

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

स्पष्टीकरण:

अनाम फ़ंक्शन ने एक और अनाम फ़ंक्शन लौटाया। इस फ़ंक्शन की मूल रूप से पारित होने की पहुंच है topicId, इसलिए यह एक त्रुटि नहीं करेगा। पहले अनाम फ़ंक्शन को तुरंत पासिंग कहा जाता है topicId, इसलिए देरी से पंजीकृत फ़ंक्शन topicIdको कॉलिंग के माध्यम से कॉलिंग के समय पहुंच प्राप्त होती है ।

या

यह मूल रूप से इसमें परिवर्तित होता है:

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

संपादित करें: मैंने एक ही जवाब देखा, इसलिए उसकी ओर देखें। लेकिन मैंने उसका जवाब नहीं चुराया! मैं देखना भूल गया। स्पष्टीकरण पढ़ें और देखें कि क्या यह कोड को समझने में मदद करता है।


यह सबसे अच्छा जवाब है। इनमें से बहुत सारे समाधान समयावधि का सम्मान नहीं करेंगे। हालाँकि, आप पहले अनाम फ़ंक्शन को कोष्ठक में क्यों लपेट रहे हैं? मुझे नहीं लगता कि वे इसे पूरा करने के लिए आवश्यक हैं।
रॉबर्ट हेंडरसन

यह सबसे अच्छा उत्तर है 👍, लेकिन एक क्लोन करना था क्योंकि जब समय जैसे मूल्यों topicIdमें परिवर्तन होता है वैसे ही मूल्य भी बदल जाते हैं। एक क्लोन ने इसे तय किया
pariola

10

बदलने के

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

साथ में

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

या बेहतर अभी भी, एक अनाम फ़ंक्शन के साथ स्ट्रिंग अभिव्यक्ति को बदलें

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

संपादित करें:

ब्राउनस्टोन की टिप्पणी गलत है, यह इरादा के अनुसार काम करेगा, जैसा कि फायरबग कंसोल में इसे चलाकर दिखाया गया है

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

ध्यान दें कि मैं दूसरों के साथ सहमत हूं कि आपको एक स्ट्रिंग पास करने से बचना चाहिए setTimeoutक्योंकि यह eval()स्ट्रिंग पर कॉल करेगा और इसके बजाय एक फ़ंक्शन पास करेगा।


यह काम नहीं करेगा क्योंकि सेटिंकआउट द्वारा पोस्टिंस्केल (विषय) के परिणाम को निष्पादित किया जाएगा। आपको इसे एक फ़ंक्शन में पहले उत्तर के साथ लपेटने की आवश्यकता है, या प्रोटोटाइप के .curry () - setTimeout (postinsql.curry (topidId), 4000) जैसे सहायक का उपयोग करने की आवश्यकता है;
शकरस्टर

2
@brownstone: यह गलत है। टाइमआउट की आग लगने पर स्ट्रिंग का मूल्यांकन किया जाएगा।
माइल्स

9

आप पैरामीटर को सेटटाइमआउट कॉलबैक फ़ंक्शन में पास कर सकते हैं:

सेटटाइमआउट (कार्य, मिलीसेकंड, param1, param2, ...)

जैसे।

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

function alertMsg(message) {
    alert(message)
}

1
क्या कोई मुझे बता सकता है कि यह उत्तर पसंदीदा क्यों नहीं है? यह मेरी राय में सबसे सरल तरीका है! जैसा कि सरल हैsetTimeout( (p) => { console.log(p); }, 1000, "hi" );
मज़ार ज़ांदलिमी

1
हाँ! यह स्वीकृत उत्तर होना चाहिए। MDN से: developer.mozilla.org/en-US/docs/Web/API/…
Han

7

सेटटाइमआउट में सहायक मापदंडों के लिए सबसे आसान क्रॉस ब्राउज़र समाधान:

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

यदि आपको IE 9 और उससे कम का समर्थन करने का मन नहीं है:

setTimeout(postinsql, 4000, topicId);

डेस्कटॉप ब्राउज़र संगतता सेट करें

मोबाइल ब्राउज़र संगतता सेट करें

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout


5

मुझे पता है कि यह प्रश्न पूछे जाने के बाद 10 साल हो गए हैं, लेकिन फिर भी, अगर आपने यहां तक ​​स्क्रॉल किया है, तो मुझे लगता है कि आप अभी भी कुछ समस्या का सामना कर रहे हैं। Meder Omuraliev द्वारा किया गया समाधान सबसे सरल है और हम में से अधिकांश की मदद कर सकता है, लेकिन उन लोगों के लिए जो कोई बंधन नहीं रखना चाहते हैं, यहाँ है:

  1. सेटटाइमआउट के लिए परम का उपयोग करें
setTimeout(function(p){
//p == param1
},3000,param1);
  1. तुरंत लागू समारोह अभिव्यक्ति (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. सवाल का हल
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

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

4

मुझे पता है कि यह पुराना है, लेकिन मैं इसमें अपना (पसंदीदा) स्वाद जोड़ना चाहता था।

मुझे लगता है कि इसे प्राप्त करने के लिए एक पठनीय तरीका topicIdएक फ़ंक्शन को पास करना है, जो बदले में आंतरिक रूप से आईडी को संदर्भित करने के लिए तर्क का उपयोग करता है। यह मान तब भी नहीं बदलेगा topicIdजब बाहर में कुछ ही समय बाद बदल दिया जाएगा।

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

या छोटा:

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

4

डेविड मिस्टर के जवाब से लगता है कि मापदंडों का ध्यान रखना चाहिए जो कॉलटाइमटाइम () पर कॉल करने के तुरंत बाद बदल सकते हैं, लेकिन इससे पहले कि अनाम फ़ंक्शन कहा जाता है। लेकिन यह बहुत बोझिल है और बहुत स्पष्ट नहीं है। मैंने IIFE (तुरंत इनविटेड फंक्शन एक्सप्रेशन) का उपयोग करके बहुत ही समान काम करने का एक सुंदर तरीका खोजा।

नीचे दिए गए उदाहरण में, currentListचर IIFE को पारित किया गया है, जो इसे अपने बंद होने में बचाता है, जब तक कि विलंबित फ़ंक्शन को लागू नहीं किया जाता है। यदि currentListकोड दिखाए जाने के तुरंत बाद चर बदलता है, setInterval()तो भी सही काम करेगा।

इस IIFE तकनीक के बिना, setTimeout()फ़ंक्शन निश्चित रूप से प्रत्येक के लिए बुलाया जाएगाh2 DOM में तत्व के , लेकिन उन सभी कॉलों में केवल अंतिम 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>

4

सामान्य तौर पर, यदि आपको किसी फ़ंक्शन को विशिष्ट मापदंडों के साथ कॉलबैक के रूप में पारित करने की आवश्यकता होती है, तो आप उच्च ऑर्डर फ़ंक्शन का उपयोग कर सकते हैं। यह ES6 के साथ बहुत सुंदर है:

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

setTimeout(someFunction(params), 1000);

या अगर someFunctionपहला आदेश है:

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

यह बहुत असंगत है
user151496

सुरुचिपूर्ण वास्तव में! धन्यवाद
Velojet

3

ध्यान दें कि त्रुटि संदेश के अनुसार कारण topicId को "परिभाषित नहीं किया गया था" यह है कि यह एक स्थानीय चर के रूप में अस्तित्व में था जब सेटटाइमआउट निष्पादित किया गया था, लेकिन तब नहीं जब विलंबित कॉल पोस्टिंस्केल को हुआ। परिवर्तनीय जीवनकाल विशेष रूप से ध्यान देने के लिए महत्वपूर्ण है, खासकर जब एक वस्तु संदर्भ के रूप में "यह" गुजरने जैसी कुछ कोशिश कर रहा है।

मैंने सुना है कि आप setTimeout फ़ंक्शन के लिए तीसरे पैरामीटर के रूप में topicId पास कर सकते हैं। बहुत विस्तार नहीं दिया गया है, लेकिन मुझे इसे काम करने के लिए पर्याप्त जानकारी मिली है, और यह सफारी में सफल है। मुझे नहीं पता कि वे "मिलीसेकंड त्रुटि" के बारे में क्या मतलब रखते हैं। यहां इसकी जांच कीजिए:

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


3

मैंने इस चरण को कैसे हल किया?

ऐसे ही :

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

setTimeout किसी फ़ंक्शन के संदर्भ का इंतजार करता है, इसलिए मैंने इसे एक क्लोजर में बनाया, जो मेरे डेटा की व्याख्या करता है और मेरे डेटा के एक अच्छे उदाहरण के साथ फ़ंक्शन को वापस करता है!

शायद आप इस भाग को बेहतर बना सकते हैं:

_deepFunction(_deepData);

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

मैंने इसे क्रोम, फ़ायरफ़ॉक्स और IE पर परीक्षण किया और यह अच्छी तरह से निष्पादित होता है, मुझे प्रदर्शन के बारे में पता नहीं है लेकिन मुझे काम करने की आवश्यकता है।

एक नमूना परीक्षण:

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

हो सकता है कि आप इसे और अधिक जटिल बनाने के लिए हस्ताक्षर बदल सकते हैं:

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

और मूल प्रश्न का उत्तर देने के लिए अंतिम:

 myNass_setTimeOut( postinsql, 4000, topicId );

आशा है कि यह मदद कर सकता है!

ps: क्षमा करें, लेकिन अंग्रेजी यह मेरी मातृभाषा नहीं है!


यह अन्य उत्तरों की तुलना में अत्यधिक जटिल है।
डैन डस्केल्सस्कू

3

यह सभी ब्राउज़रों में काम करता है (IE एक ऑडबॉल है)

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

3

अगर आप वेरिएबल को पास करना चाहते हैं, तो परम इसे आजमाते हैं

यदि आवश्यकता कार्य और वर्जन के रूप में है तो यह प्रयास करें

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

यदि आवश्यकता केवल चर के रूप में परिवर्तनशील है तो यह प्रयास करें

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

आप इसे ES5 और ES6 के साथ आज़मा सकते हैं


2

आप इस तरह से 'लागू ()' की डिफ़ॉल्ट कार्यक्षमता की कोशिश कर सकते हैं, आप सरणी में अपनी आवश्यकता के रूप में अधिक संख्या में तर्क पारित कर सकते हैं

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

1

setTimeout WHAT WG द्वारा परिभाषित DOM का हिस्सा है।

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

आपको जो विधि चाहिए वह है: -

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

समय-सीमा मिलीसेकंड के बाद हैंडलर चलाने के लिए समय-सारिणी निर्धारित करता है। किसी भी तर्क को हैंडलर के माध्यम से सीधे पारित किया जाता है।

setTimeout(postinsql, 4000, topicId);

जाहिर है, IE10 में अतिरिक्त तर्कों का समर्थन किया जाता है। वैकल्पिक रूप से, आप उपयोग कर सकते हैं setTimeout(postinsql.bind(null, topicId), 4000);, हालांकि अतिरिक्त तर्क पारित करना सरल है, और यह बेहतर है।

ऐतिहासिक तथ्य: VBScript के दिनों में, JScript में, setTimeout का तीसरा पैरामीटर भाषा था, स्ट्रिंग के रूप में, "JScript" के लिए डिफ़ॉल्ट लेकिन "VBScript" का उपयोग करने के विकल्प के साथ। https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)


0

@Jiri Vetyska पोस्ट के लिए धन्यवाद, लेकिन आपके उदाहरण में कुछ गड़बड़ है। मुझे उस लक्ष्य को पारित करने की आवश्यकता थी जो समयबद्ध कार्य करने के लिए (इस) को हॉवर किया गया है और मैंने आपके दृष्टिकोण की कोशिश की। IE9 में परीक्षण किया गया - काम नहीं करता है। मैंने कुछ शोध भी किए और यह प्रतीत होता है कि जैसा कि यहां बताया गया है कि तीसरा पैरामीटर स्क्रिप्ट भाषा का उपयोग किया जा रहा है। अतिरिक्त मापदंडों के बारे में कोई उल्लेख नहीं।

इसलिए, मैंने @ मध्यस्थ के उत्तर का पालन किया और इस कोड के साथ अपना मुद्दा हल किया:

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

आशा है, यह किसी और के लिए उपयोगी है।


0

जैसा कि IE में तीसरे ऑप्टोनल पैरामीटर के साथ एक समस्या है और क्लोजर का उपयोग हमें चर (उदाहरण के लिए एक लूप में) को बदलने से रोकता है और अभी भी वांछित परिणाम प्राप्त कर रहा है, मैं निम्नलिखित समाधान का सुझाव देता हूं।

हम इस तरह पुनरावृत्ति का उपयोग करने की कोशिश कर सकते हैं:

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

हमें यह सुनिश्चित करने की आवश्यकता है कि इन चर को और कुछ नहीं बदलता है और हम अनंत पुनरावृत्ति से बचने के लिए एक उचित पुनरावर्तन स्थिति लिखते हैं।


0

// ये तीन बहुत ही सरल और संक्षिप्त उत्तर हैं:

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

प्रश्न का उत्तर दे रहे हैं, लेकिन 2 तर्कों के साथ एक सरल जोड़ समारोह द्वारा।

var x = 3, y = 4;

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

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


-1

मुझे लगता है कि आप चाहते हैं:

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

1
मैंने ऐसे उदाहरणों में भाग लिया है जहाँ वह काम नहीं करता है (हमेशा 'फ़ंक्शन नहीं परिभाषित' त्रुटि के परिणामस्वरूप) लेकिन अनाम फ़ंक्शन का उपयोग करने से काम होता है। यह देखते हुए निराशा होती है कि सभी का कहना है कि उपरोक्त वाक्यविन्यास हमेशा काम करना चाहिए। (यह हो सकता है कि jQuery किसी तरह '' स्ट्रिंग के रूप में उद्धरण 'विधि के रूप में हो जाता है?)
डीए।

6
मान लीजिए कि topicId एक फ़ंक्शन है ... या ऑब्जेक्ट है। यह काम नहीं करेगा!
सेरेफिम

यदि आप वास्तव में इस विधि के साथ आगे बढ़ना चाहते हैं JSON.stringify, तो नियमित वस्तुओं और सरणियों के लिए उपयोग करें , और फिर JSON.parseफ़ंक्शन के अंदर उपयोग करें । हालाँकि, ऑब्जेक्ट के तरीके हैं, तो सभी व्यवहार खो जाएगा।
डेर्थकैडस

-2

// ये तीन बहुत ही सरल और संक्षिप्त उत्तर हैं:

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');
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.