[javascript] setTimeout () 콜백에 매개 변수를 전달하려면 어떻게해야합니까?

다음과 같은 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은 모든 추가 매개 변수를 함수에 전달하여 처리 될 수 있도록합니다.

익명 함수는 매우 기본적인 작업을 수행 할 수 있지만 “this”를 사용해야하는 개체의 인스턴스 내에서는 작동시킬 방법이 없습니다. 익명 함수는 “this”를 변경하여 창을 가리 키므로 객체 참조를 잃게됩니다.


답변

이것은 이미 “올바른”답변을 가진 매우 오래된 질문이지만 아무도 언급하지 않은 다른 접근법을 언급한다고 생각했습니다. 이것은 훌륭한 밑줄 라이브러리 에서 복사하여 붙여 넣습니다 .

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

당신의 setTimeout 호출 함수에 원하는만큼 당신은 많은 인수로 전달할 수 있습니다 추가 보너스 (물론, 일반적으로 보너스) 당신의 setTimeout를 호출 할 때 함수에 전달되는 인수의 값이 냉동만큼 그들이 값을 변경 그렇다면, setTimeout ()이 호출 될 때와 시간이 초과 될 때 사이의 어느 시점에서, 글쎄 … 그게 더 이상 너무 실망스럽지 않습니다 🙂

여기에 내가 무슨 뜻인지 볼 수 있는 바이올린 이 있습니다.


답변

나는 최근 setTimeout루프 를 사용해야하는 독특한 상황을 겪었다 . 이를 이해하면에 매개 변수를 전달하는 방법을 이해하는 데 도움이됩니다 setTimeout.

방법 1

사용 forEachObject.keysSukima의에 따라, 제안 :

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

당신이 사용할 수없는 경우 또는 forEachbind, 사용 인생을 :

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

방법 4

그러나 IE <10에 관심이 없다면 Fabio의 제안을 사용할 수 있습니다 .

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.


답변

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


답변

일부 답변은 정확하지만 복잡합니다.

나는이 질문을 정확하게 해결하기 위해 지나치게 복잡한 코드를 계속 사용하기 때문에 4 년 후에 다시 대답하고 있습니다. 우아한 해결책이 있습니다.

우선, setTimeout을 호출 할 때 느린 “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);
}

구문이 작동합니다. 그러나 settopic이 호출 될 때까지, 즉 4 초 후에 XHR 객체가 동일하지 않을 수 있습니다. 따라서 변수미리 바인딩하는 것이 중요 합니다 .