javascript - আমি কিভাবে একটি setTimeout() কলব্যাকের জন্য একটি পরামিতি পাস করতে পারি?




parameters callback (14)

আমার কাছে এমন কিছু জাভাস্ক্রিপ্ট কোড আছে যা দেখে মনে হচ্ছে:

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

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

আমি একটি ত্রুটি topicId যে topicId সংজ্ঞায়িত করা হয় না। আমি setTimeout() ফাংশন ব্যবহার করার আগে সবকিছু কাজ করে।

আমি আমার postinsql(topicId) ফাংশন কিছু সময় পরে বলা চাই। আমার কি করা উচিৎ?


@ জিরী ভেটিসকা পোস্টের জন্য ধন্যবাদ, কিন্তু আপনার উদাহরণে কিছু ভুল আছে। আমি লক্ষ্যটি পূরণ করতে চাই যা এটি (আউট) একটি টাইম আউট ফাংশনে লুকিয়ে আছে এবং আমি আপনার পদ্ধতির চেষ্টা করেছি। IE9 পরীক্ষিত - কাজ করে না। আমি কিছু গবেষণাপত্রও তৈরি করেছি এবং মনে হচ্ছে যে w3schools.com/jsref/met_win_settimeout.asp তৃতীয় প্যারামিটারটি স্ক্রিপ্ট ভাষা ব্যবহার করা হচ্ছে। অতিরিক্ত পরামিতি সম্পর্কে কোন উল্লেখ নেই।

তাই, আমি @ মেডারের উত্তরটি অনুসরণ করেছি এবং এই কোডটি দিয়ে আমার সমস্যা সমাধান করেছি:

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

আশা করি, এটি অন্য কারো জন্য দরকারী।


Hobblin ইতিমধ্যে প্রশ্ন এই মন্তব্য, কিন্তু এটা সত্যিই একটি উত্তর হতে হবে!

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/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout


SetTimeout মধ্যে পরামিতি সমর্থন করার জন্য সবচেয়ে সহজ ক্রস ব্রাউজার সমাধান:

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

আপনি IE 9 এবং নিম্ন সমর্থন না মানা না হলে:

setTimeout(postinsql, 4000, topicId);

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


আধুনিক ব্রাউজারগুলিতে, "সেটটাইমআউট" টাইমারের শেষে অভ্যন্তরীণ ফাংশনে প্যারামিটার হিসাবে প্রেরিত তৃতীয় প্যারামিটার গ্রহণ করে।

উদাহরণ:

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

আরো বিস্তারিত:


আপনি প্যারামিটার হিসাবে পরিবর্তন করতে চান তাহলে প্যারামিটার চেষ্টা করে দেখুন

প্রয়োজন হলে পার্ম হিসাবে ফাংশন এবং var হয় তারপর এই চেষ্টা করুন

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

যদি প্রয়োজন শুধুমাত্র একটি প্যারামিটার হিসাবে ভেরিয়েবল তারপর এই চেষ্টা করুন

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

আপনি ES5 এবং ES6 দিয়ে এটি চেষ্টা করতে পারেন


আমার উত্তর:

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

ব্যাখ্যা:

বেনামী ফাংশন আরেকটি বেনামী ফাংশন তৈরি করে তৈরি। এই ফাংশনটি মূলত পাস করা topicId অ্যাক্সেস আছে, তাই এটি একটি ত্রুটি তৈরি করবে না। প্রথম অনামী ফাংশনটি অবিলম্বে বিষয় topicId পাস করা হয়, সুতরাং বিলম্বের সাথে নিবন্ধিত ফাংশনটি কল করার সময়, topicId সময় topicId অ্যাক্সেস করতে পারে।

অথবা

এটি মূলত রূপান্তরিত হয়:

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

সম্পাদনা করুন: আমি একই উত্তর দেখেছি, তাই তার দিকে তাকান। কিন্তু আমি তার উত্তর চুরি করিনি! আমি শুধু দেখতে ভুলে গেছি। ব্যাখ্যা পড়ুন এবং এটি কোড বুঝতে সাহায্য করে দেখুন।


আমি কিভাবে এই পর্যায়ে সমাধান?

এমনি :

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: দুঃখিত কিন্তু ইংরেজি আমার মাতৃভাষা নয়!


আমি মনে করি আপনি চান:

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

এই সব ব্রাউজারে কাজ করে (IE একটি oddball হয়)

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

এটি একটি পুরানো "সঠিক" উত্তর দিয়ে একটি পুরানো প্রশ্ন কিন্তু আমি ভাবলাম যে আমি এখানে অন্য কোন পদ্ধতি উল্লেখ করেছি যা এখানে উল্লেখ করা হয়নি। এটি চমৎকার underscore লাইব্রেরি থেকে অনুলিপি এবং আটকানো হয়েছে:

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

আপনি সেটমাইমআউট নামে পরিচিত ফাংশনটি পছন্দ করতে পারেন এবং একটি অতিরিক্ত বোনাস হিসাবে (ভাল, সাধারণত বোনাস) আপনার ফাংশনে প্রেরিত আর্গুমেন্টগুলির মান হ্রাস করা হয় যখন আপনি সেটটাইমআউট কল করেন, তাই যদি তারা মান পরিবর্তন করে কিছু সময় যখন setTimeout () বলা হয় এবং যখন এটি বার বার হয়, ভাল ... যেটি এখন আর হতাশভাবে হতাশ হয় না :)

এখানে একটি উষ্ণতা যেখানে আপনি কি বলতে পারেন দেখতে পারেন।


কিছু গবেষণা এবং পরীক্ষার পরে, শুধুমাত্র সঠিক বাস্তবায়ন হয়:

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

setTimeout আপনার ফাংশনে সমস্ত অতিরিক্ত পরামিতি পাস করবে যাতে তাদের সেখানে প্রক্রিয়া করা যেতে পারে।

বেনামী ফাংশনটি খুব মৌলিক উপাদানগুলির জন্য কাজ করতে পারে, কিন্তু এমন একটি বস্তুর উদাহরণ হিসাবে যেখানে আপনাকে "এই" ব্যবহার করতে হবে, এটি কার্যকর করার কোন উপায় নেই। কোনও বেনামী ফাংশন উইন্ডোতে নির্দেশ করতে "এই" পরিবর্তন করবে, তাই আপনি আপনার বস্তুর রেফারেন্সটি হারাবেন।


ডেভিড মিস্টারের উত্তরটি সেই সময়সীমাগুলির যত্ন নিতে বলে মনে হয় যা সেটমাইম () এ কল করার পরে অবিলম্বে পরিবর্তিত হতে পারে তবে বেনামী ফাংশন বলা হয়। কিন্তু এটি খুব কষ্টকর এবং খুব সুস্পষ্ট নয়। আমি আইফাই (অবিলম্বে ফাংশন এক্সপ্রেশন inviked) ব্যবহার করে একই জিনিস খুব সুন্দর করার একটি মার্জিত উপায় আবিষ্কৃত।

নিচের উদাহরণে, বর্তমান তালিকা পরিবর্তনশীল আইফিকে প্রেরণ করা হয়, যা বিলম্বিত ফাংশনটি আমন্ত্রিত না হওয়া পর্যন্ত এটি বন্ধ করে সংরক্ষণ করে। পরিবর্তনশীল বর্তমান তালিকা কোড দেখানোর পরে অবিলম্বে পরিবর্তন, এমনকি setInterval() সঠিক জিনিস করতে হবে।

এই IIFE টেকনিক ছাড়া, setTimeout() ফাংশন স্পষ্টভাবে DOM- এ প্রতিটি h2 উপাদানের জন্য কল করা হবে তবে সমস্ত কলগুলি শেষ 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>

লক্ষ্য করুন যে বিষয়টি আইডি ত্রুটির বার্তা প্রতি "সংজ্ঞায়িত না" ছিল, এটি সেটটি টাইমআউট কার্যকর হওয়ার সময় স্থানীয় ভেরিয়েবল হিসাবে বিদ্যমান ছিল, কিন্তু পোস্টিনস্কএলে বিলম্বিত কল কখন ঘটেনি। পরিবর্তনশীল জীবনকাল বিশেষ করে মনোযোগ দিতে গুরুত্বপূর্ণ, বিশেষত যখন এটি "বস্তু" হিসাবে একটি বস্তু রেফারেন্স হিসাবে পাস করার চেষ্টা করে।

আমি শুনেছি যে আপনি topicIdটি সেটটাইম ফাংশনে তৃতীয় প্যারামিটার হিসাবে পাস করতে পারেন। অনেক বিস্তারিত দেওয়া হয় নি তবে আমার কাছে কাজ করার জন্য যথেষ্ট তথ্য পেয়েছি, এবং এটি সাফারিতে সফল হয়েছে। আমি জানি না তারা "মিলিসেকেন্ড ত্রুটি" সম্পর্কে কী বুঝায়। এখানে এটি পরীক্ষা করে দেখুন:

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


সাধারণভাবে, যদি আপনি একটি নির্দিষ্ট ফরম্যাটের সাথে একটি কলব্যাক হিসাবে একটি ফাংশন পাস করতে চান, আপনি উচ্চ ক্রম ফাংশন ব্যবহার করতে পারেন। এই ES6 সঙ্গে সুন্দর মার্জিত হয়:

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

setTimeout(someFunction(params), 1000);

অথবা যদি কিছু someFunction প্রথম অর্ডার হয়:

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






settimeout