SetTimeout不能延迟函数调用

17

请问有人能告诉我为什么下面代码中使用的setTimeout不起作用吗?它只是立即运行函数。

function change_txt_font(elem, id, text_fnt){
    current_width = parseInt($('#span_text'+id).css('width')); 
    current_height = parseInt($('#span_text'+id).css('height')); 
    current_font_size = parseInt($("#span_text"+id).css("font-size"));

    parent.document.getElementById(elem+'_f').value=text_fnt;

    $('#span_text'+id).css('font-family',text_fnt);
    $('#'+elem).css('font-family',text_fnt); 
    setTimeout(adjust_for_font(id),2000);
    }

function adjust_for_font(id){
        alert("function")
        alert("id = "+id)
    new_height = parseInt($('#span_text'+id).css('height'));
    new_width = parseInt($('#span_text'+id).css('width'));
    width_ratio = parseFloat(current_width/new_width)
    height_ratio = parseFloat(current_height/new_height)
    new_font_size = current_font_size * Math.min(width_ratio,height_ratio)
    $("#text"+id).css("font-size", (parseFloat(new_font_size) - 1) + "px");
    $("#span_text"+id).css("font-size", (parseFloat(new_font_size) - 1) + "px");
    document.getElementById("form_front_text"+id).submit();
}document.getElementById("form_front_text"+id).submit();
}

需要任何帮助。


4
setTimeout(function() { adjust_for_font(id); }, 2000) 可以翻译为:在2000毫秒后,执行函数adjust_for_font(id) - Sim
谢谢Sim,你真是个明星!我还在逐渐适应JavaScript,有时候表现得不够好!再次感谢。 - Mark_54
7个回答

46

问题出在这一行

setTimeout(adjust_for_font(id),2000);

这并不会安排调用adjust_for_font(id),而是直接调用函数并安排返回值的调度。如果要安排函数的调用,请将调用包装在lambda中。

setTimeout(function() { adjust_for_font(id); },2000);

这正是我所需要的,谢谢! - RichieMN
对于未来的读者,使用ES6,你也可以这样做 setTimeout( () => {adjust_for_font(id);}, 2000); 这可以避免引用this时出现问题。更多信息可在此处找到。 - Jwok

6

如果不在函数周围加上引号,该函数将立即执行,setTimeout会运行(但不会处理函数),你会想知道到底发生了什么。

setTimeout的设计是这样运行的:

setTimeout('adjust_for_font',2000);

或者在回调函数中使用匿名函数也是另一个选项:

setTimeout(function(){adjust_for_font(id);}, 2000);

“左思右想,还是不知道到底发生了什么” - 是的,这几乎概括了我目前的JavaScript编程体验!! - Mark_54

4

更改

setTimeout(adjust_for_font(id),2000);

to

setTimeout("adjust_for_font(id)",2000);

1
不是一个坏建议,但在某些版本的Safari上仍然无法工作。最好将其设置为函数中:setTimeout(function(){ adjust_for_font(id); }, 2000); - SpYk3HH

4
这应该就可以解决问题了:
setTimeout(adjust_for_font, 2000, id);

我将函数名传递,以便在2000毫秒后执行。在你的代码中,你正在传递adjust_for_font的结果。函数名后面的括号会导致它在解析时立即执行。


并非所有的浏览器都支持在延迟之后为指定函数提供参数的setTimeout()语法。像其他答案中那样使用匿名函数可以在所有浏览器中运行。 - nnnnnn

3

按照你的写法,好像adjust_for_font(id)的输出是setTimeout的第一个参数的输入。第一个参数应该是函数,而不是函数的结果。请尝试使用以下代码替换...

setTimeout(function() {
    adjust_for_font(id);
},2000);

2

SetTimeout语法是setTimeout(function, 毫秒数, 参数1, 参数2, ...)

这里的“function”不是函数调用,而是真正的函数。

因此,您需要将代码更改为

setTimeout(adjust_for_font,2000,id); (注意:参数id应该在毫秒数参数之后传递)

或者你也可以将第一个参数设置为以下内容

setTimeout(function() { adjust_for_font(id); },2000);


1
这是我个人的经验。仅仅指定setTimeout()会导致它在页面加载时执行,即使它的父函数没有被调用。将它变成一个变量像这样就可以工作了。

after

这是我的经验。仅仅指定setTimeout()会导致它在页面加载时执行,即使它的父函数没有被调用。将其赋值给一个变量就可以解决这个问题。
function xyz(){
  //do something if needed
  setTimeout(function abc, duration);
  //setTimeout will be executed even before xyz() call
}

之后

function xyz(){
  //do something if needed
  var t=setTimeout(function abc, duration);
  //this time, setTimeout will be executed upon xyz() call and not upon pageload
}

JS 真是愚蠢,但这比我见过的几乎所有东西都要好!虽然...在我的情况下这是解决方法,所以你有我的感谢! - Cowwando

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接