SetTimeout с аргументами
имея небольшую головную боль при попытке решить эту проблему. То, что я хочу сделать, это создать пользовательский параметр setTimeout с аргументами с функцией, чтобы создать функцию для ее передачи. Позвольте мне объяснить по коду:
Хотите избежать:
function makeTimeout(serial){
serial.close();
}
setTimeout(makeTimeout(sp.name), 250);
что я хочу сделать, так или иначе просто назовите 1 лайнер, например:
setTimeout(function(arg1){ .... }(argument_value), 250);
Можно ли это сделать или вы можете передать только функцию без аргументов?
Ответы
Ответ 1
Вы можете передать ему анонимную функцию, которая вызывает makeTimeout
с данными аргументами:
setTimeout(function () {
makeTimeout(sp.name);
}, 250);
Существует также альтернатива, используя bind
:
setTimeout(makeTimeout.bind(this, sp.name), 250);
Эта функция, однако, является функцией ECMAScript 5th Edition, еще не поддерживаемой во всех основных браузерах. Для совместимости вы можете включить bind
источник, который доступен в MDN, что позволяет использовать его в браузерах, которые его не поддерживают.
DEMO.
Ответ 2
Если вы не хотите объявлять отдельную функцию, вы можете использовать сразу вызванное выражение функции и закрытие, например.
// Parameter to use
var bar = 'bar';
// Function to call
function foo(arg) {
alert(arg);
}
// Go…
setTimeout(
(function(arg1){
return function(){
foo(arg1);
};
}(bar)), 2000);
В качестве альтернативы вы можете использовать конструктор функций:
setTimeout( Function('foo(bar)'), 2000);
Или вы можете использовать строку:
setTimeout('foo(bar)', 1000);
что по существу одно и то же. Теперь ждите воплей ", но это похоже на использование eval, и все знают, что eval - это зло и серьезное нарушение безопасности - все ваши первенцы обречены!"
Но серьезно, eval
(и конструктор Function) неэффективны и могут привести к ленивому программированию, поэтому используйте другой вариант, например, первый выше.
Ответ 3
Кажется, что функция была добавлена к некоторым параметрам пропуска браузера в setTimeout:
Синтаксис : setTimeout (function (p1,p2) {},1000,p1,p2);
(добавьте столько параметров, сколько хотите)
Если вы хотите, чтобы он работал повсюду, вы можете использовать прилагаемый код.
Примечание. Если вы хотите установить тайм-аут сразу после его установки, лучше всего использовать параметр обратного вызова и сделать его там
, например
installSwizzledTimeout(function(param1,param2){
setTimeout(myFunc,200,param1,param2);},param1,param2);
}
Это связано с тем, что он использует трюк, чтобы определить, требуется ли это, установив очень короткий тайм-аут и подсчитав параметры.
window.swizzledSetTimeout = function (fn, ms) {
if (arguments.length === 2) {
//console.log("Bypassing swizzledSetTimeout");
return window.originalSetTimeout(fn, ms);
} else {
var args = [];
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i])
};
//console.log("Setting swizzledSetTimeout for function (",args,") {...} in ",ms," msec");
var retval = window.originalSetTimeout(function () {
//console.log("Invoking swizzledSetTimeout for function (",args,") {...}");
fn.apply(null, args);
}, ms);
return retval;
}
}
function installSwizzledTimeout(cb) {
var args = [];
for (i = 1; i < arguments.length; i++) {
args.push(arguments[i])
};
setTimeout(function (arg) {
//console.log("arguments.length:",arguments.length,window.setTimeout.toString());
if (arguments.length == 0) {
function doInstall() {
//console.log("Installing new setTimeout");
window.originalSetTimeout = window.setTimeout;
window.setTimeout = function setTimeout() {
return window.swizzledSetTimeout.apply(null, arguments);
};
if (cb) {
cb.apply(null, args);
};
}
if (window.setTimeout.toString().indexOf("swizzledSetTimeout") < 0) {
doInstall();
}
} else {
//console.log("existing set time supports arguments ");
if (cb) {
cb.apply(null, args);
};
}
}, 0, 1, 2, 3, 4);
}