どのようにしていただくためには、パラメータをチューニングsetTimeout()コールバック?

StackOverflow https://stackoverflow.com/questions/1190642

質問

しているのか教えてくださいJavaScriptコードを次のように記述されています。

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) 機能を呼び出します。どうしたらよいですか?

役に立ちましたか?

解決

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

必要なもの飼料匿名としての機能のパラメータの代わりに、文字列後者の方法ではないについては、ECMAScript仕様がブラウザだけで甘.この溶液になっ頼を渡す文字列として機能"を利用の場合 setTimeout() または setInterval(), では遅いので評価できるのではない。

更新:

としてHobblinするだろうと思って、このコメントは、今までに引数の関数内setTimeout用 Function.prototype.bind()

例:

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

他のヒント

モダンブラウザの"setTimeout"を受けた第三パラメータに送信されるパラメータとしての内部機能末ますテットンと申します。

例:

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

詳細:

いくつかの研究とテストを行った後、唯一の正しい実装があります:

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

のsetTimeout彼らはそこに処理することができますので、あなたの関数にすべての余分なパラメータを渡します。

匿名関数は、非常に基本的なもののために働くことができますが、あなたが使用する必要がオブジェクトのインスタンス内で「これは」、それを動作させる方法はありません。 任意の無名関数を使用すると、あなたのオブジェクト参照を失うことになるので、「これは」、ウィンドウを指すように変更されます。

このは、既に「正しい」答えと非常に古い質問ですが、私は誰もがここで言及していないことを別のアプローチを言及しようと思いました。これは、優れた のライブラリーを強調します:

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

あなたがsetTimeoutをのことで呼び出された関数にとの追加ボーナス(まあ、通常ボーナス)として好きなあなたの関数に渡される引数の値が凍結されているなど、多くの引数を渡すことができますときのsetTimeout()が呼び出されたとき、彼らは間のある時点で値を変更するので、もしあなたが、のsetTimeoutを呼び出し、ときにそれをタイムアウトし、よく...それはもうそれほど恐ろしくイライラはありません。)

ここでは、私が何を意味するか見ることができますフィドルのだ。

私は最近になってようやく全体の状況を使用する必要があ setTimeout a ループ.これらを理解でをご理解いただくためにどのようにパスパラメータ setTimeout.

方法1

使用 forEachObject.keys, どのスキマス の提案:

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

くつ家 < 10その利用Fabioの の提案:

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

法5(ES6)

使用ブロックscoped変数:

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

いうものの使用をお勧めし Object.keysforEach にES6.

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 /機能/バインド#With_setTimeoutする

いくつかの答えは正しいが、複雑です。

私は、これは再び、4年後、私はまだ、まさにこの問題を解決するために過度に複雑なコードに実行するための回答しています。エレガントな解決策があります。

それが効果的に遅い「evalの」関数の呼び出しを呼び出すためのsetTimeoutを呼び出すときに

まず、最初のパラメータとして文字列を渡しません。

それでは、どのように我々は、タイムアウト関数にパラメータを渡すのですか?クロージャを使用することによります:

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

構文がうまくいきます。しかしsettopicが呼び出された時点で、すなわち4秒後、XHRオブジェクトは同じでなくてもよいです。したがって、それはhref="https://stackoverflow.com/questions/21212928/use-ajax-request-json-output-in-settimeout-function/21213598#21213598">事前バインド変数を

私の答えます:

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

編集:私は同じ答えを見たので、彼を見てください。しかし、私は彼の答えを盗んでいません!私はただ見て忘れてしまいました。説明を読み、それがコードを理解するのに役立ちますかどうかを確認します。

交換

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

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

またはより良いものに置き換え文字列表現匿名機能

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

編集:

Brownstoneのコメントが正しくない場合、このとして、このように走りこれを開いているのがfirebugのコンソール

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

こんagreeance他の人がどうしたらよいかということですぐる文字列 setTimeout この通 eval() の文字列で渡ります。

のsetTimeoutのパラメータを支持するための最も簡単なクロスブラウザ溶液

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

あなたはIE 9とをサポートしていない気にしない場合は下:

setTimeout(postinsql, 4000, topicId);

setTimeoutをデスクトップブラウザの互換性

setTimeoutをモバイルブラウザの互換性

https://developer.mozilla.org/en-米国/ドキュメント/ウェブ/ API / WindowTimers / setTimeoutをする

私はそれが古いです知っているが、私はこれに私の(優先)の風味を追加したい。

私はこれを達成するために、かなり読みやすい方法を順番に内部でトピックIDを参照するために引数を使用する関数に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);

その答えによるデビッド-マイスターのようにパラメータを変更直後に呼び出setTimeout()の直前に匿名の関数が呼び出されます。"お取り寄せ"も掲載し面倒なものではないはずである。またこれまでにないのほとんど同じものを使用IIFE(直inviked機能発現).

以下の例では、 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>

これはすべてのブラウザ(IEは変わり者である)で動作します。

setTimeout( (function(x) {
return function() {
        postinsql(x);
    };
})(topicId) , 4000);
あなたが特定のパラメータを持つコールバックとして関数を渡す必要がある場合は、

一般的に、あなたは、より高次の機能を使用することができます。これはES6とかなり洗練されてます:

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

setTimeout(someFunction(params), 1000);

またはsomeFunctionが最初の注文の場合:

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

TOPICIDは、エラーメッセージごとに「定義されていません」された理由は、遅延コールが起こっpostinsqlするとき、それはsetTimeoutメソッドを実行したときに、ローカル変数として存在していたが、ないということであることに注意してください。変数の寿命は特に「この」オブジェクト参照として渡すようなものをしようとしたとき、に注意を払うことが特に重要です。

私はあなたがsetTimeout関数の3番目のパラメータとして渡すことができTOPICIDことを聞きました。あまり詳細が与えられたが、私はそれを動作させるために十分な情報を得て、それはSafariで成功したのですされています。私は、彼らはしかし、「ミリ秒の誤差」について何を意味するのか分かりません。ここでそれをチェックアウト:

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

私は、この段階の解決方法は?

ちょうどそのような:

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

のsetTimeout関数への参照を待って、私は私のデータをinterprete閉鎖、それを作成し、私のデータの良いインスタンスに機能を返す!

たぶん、あなたはこの部分を改善することができます:

_deepFunction(_deepData);

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

私は、パフォーマンスのことは知らないが、私は仕事ができること、それを必要と、私はクロム、Firefoxと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)
}

そしてfinaly元の質問に答えるために:

 myNass_setTimeOut( postinsql, 4000, topicId );

は、それが役立つことを願って!

PS:!申し訳ありませんが、英語、それは私の母国語ではありません。

あなたはparamはこれを試すことができますとして変数を渡したい場合は、

要件はparmasとしての機能とVARである場合は、

そして

このを試してみてください
setTimeout((param1,param2) => { 
     alert(param1 + param2);
     postinsql(topicId);
},2000,'msg1', 'msg2')
要件はのparamsとして変数だけである場合は、

これを試してみてください

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

あなたはES5およびES6でこれを試すことができます。

あなたはこのようなものは、あなたが配列にあなたの条件として、引数の数より多くを渡すことができます「)(適用」のデフォルトの機能を試すことができます。

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

を渡すことができるパラメータのsetTimeoutコールバック関数として

setTimeout(機能(ミリ秒単位param1,param2,...)

例えば.

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

function alertMsg(message) {
    alert(message)
}

@Jiri Vetyskaポストに感謝、しかし、あなたの例で間違った何かがあります。 私がタイムアウトしました関数にアウト(この)推移しているターゲットを渡すために必要な、私はあなたのアプローチを試してみました。 IE9でテスト - 動作しません。 私はまた、いくつかの研究を行い、先の尖ったのがここで三番目のパラメータをに、スクリプト言語であることが表示されます使用されています。追加のパラメータについては言及ます。

だから、私は、@ MEDERの答えを踏襲し、このコードと私の問題を解決します:

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

希望、これは他の誰かのために便利です。

が第optonalパラメータに問題が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);
}

私たちは、他に何もこれらの変数を変更しないと、私たちは無限の再帰を避けるために、適切な再帰条件を記述していることを確認する必要があります。

//これらは、3つの非常にシンプルで簡潔な答えがあります:

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

私は、あなたがしたいと思います。

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

//これらは、3つの非常にシンプルで簡潔な答えがあります:

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');
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top