매개 변수를 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()
or를 사용할 때 문자열을 '함수'로 전달하는 것에 의존하지 마십시오 setInterval()
. 평가해야하고 옳지 않기 때문에 속도가 느립니다.
최신 정보:
Hobblin이 질문에 대한 의견에서 말했듯이 이제 setTimeout 내부의 함수에 인수를 전달할 수 있습니다. Function.prototype.bind()
예:
setTimeout(postinsql.bind(null, topicId), 4000);
최신 브라우저에서 "setTimeout"은 타이머가 끝날 때 내부 함수에 매개 변수로 전송되는 세 번째 매개 변수를 수신합니다.
예:
var hello = "Hello World";
setTimeout(alert, 1000, hello);
자세한 내용은:
- https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setTimeout
- http://arguments.callee.info/2008/11/10/passing-arguments-to-settimeout-and-setinterval/
조사 및 테스트를 수행 한 후 올바른 구현은 다음과 같습니다.
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
사용 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
, 사용 인생을 :
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
with 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 객체가 동일하지 않을 수 있습니다. 따라서 변수 를 미리 바인딩하는 것이 중요 합니다 .
내 대답 :
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
})();
문자열을 setTimeout
호출 eval()
하고 대신 함수 를 전달하므로 문자열 전달을 피해야한다는 다른 사람들과 동의 합니다.
setTimeout에서 매개 변수를 지원하는 가장 쉬운 크로스 브라우저 솔루션 :
setTimeout(function() {
postinsql(topicId);
}, 4000)
IE 9 이하를 지원하지 않아도 괜찮다면 :
setTimeout(postinsql, 4000, topicId);
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
나는 그것이 오래되었다는 것을 알고 있지만 이것에 나의 (선호하는) 맛을 더하고 싶었습니다.
이 작업을 수행하는 꽤 읽기 쉬운 방법은을 topicId
함수 에 전달 하는 것입니다. 그러면 내부적으로 주제 ID를 참조하는 인수를 사용합니다. 이 값은 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);
David Meister의 대답은 setTimeout () 호출 직후 익명 함수가 호출되기 전에 변경 될 수있는 매개 변수를 처리하는 것 같습니다. 하지만 너무 번거롭고 명확하지 않습니다. 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>
이것은 모든 브라우저에서 작동합니다 (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가 "정의되지 않음"인 이유는 setTimeout이 실행될 때 로컬 변수로 존재했지만 postinsql에 대한 지연된 호출이 발생했을 때가 아니기 때문입니다. 가변 수명은 특히 "this"를 객체 참조로 전달하는 것과 같은 작업을 시도 할 때주의해야 할 중요한 사항입니다.
setTimeout 함수에 세 번째 매개 변수로 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은 함수에 대한 참조를 기다리므로 클로저에서 생성하여 데이터를 해석하고 내 데이터의 좋은 인스턴스로 함수를 반환합니다!
이 부분을 개선 할 수 있습니다.
_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 );
그것이 도움이 될 수 있기를 바랍니다!
추신 : 미안하지만 영어 내 모국어가 아닙니다!
변수를 매개 변수로 전달하려면 이것을 시도하십시오.
요구 사항이 function이고 var as parmas이면 이것을 시도하십시오.
setTimeout((param1,param2) => {
alert(param1 + param2);
postinsql(topicId);
},2000,'msg1', 'msg2')
요구 사항이 매개 변수로만 변수이면 다음을 시도하십시오.
setTimeout((param1,param2) => { alert(param1 + param2) },2000,'msg1', 'msg2')
ES5 및 ES6에서 이것을 시도 할 수 있습니다.
다음과 같은 'apply ()'의 기본 기능을 시도해 볼 수 있으며 배열의 요구 사항으로 더 많은 인수를 전달할 수 있습니다.
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
}
희망, 이것은 다른 사람에게 유용합니다.
IE의 세 번째 optonal 매개 변수에 문제가 있고 클로저를 사용하면 변수 (예 : 루프)를 변경하고 원하는 결과를 얻을 수 없으므로 다음 솔루션을 제안합니다.
다음과 같이 재귀를 사용해 볼 수 있습니다.
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);
}
이 변수를 변경하지 않고 무한 재귀를 피하기 위해 적절한 재귀 조건을 작성해야합니다.
// 다음은 세 가지 매우 간단하고 간결한 답변입니다.
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);
// 다음은 세 가지 매우 간단하고 간결한 답변입니다.
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');
참고 URL : https://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback
'program story' 카테고리의 다른 글
단위, 기능, 승인 및 통합 테스트의 차이점은 무엇입니까? (0) | 2020.09.29 |
---|---|
"~"(물결표 / 구불 구불 / 뒤틀림) CSS 선택기는 무엇을 의미합니까? (0) | 2020.09.29 |
함수에 return 문이 하나만 있어야합니까? (0) | 2020.09.29 |
"인터페이스 프로그래밍"이란 무엇을 의미합니까? (0) | 2020.09.29 |
이러한 구조가 사전 및 사후 증가 정의되지 않은 동작을 사용하는 이유는 무엇입니까? (0) | 2020.09.29 |