Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
321 views
in Technique[技术] by (71.8m points)

javascript - 为什么setTimeout(fn,0)有时有用?(Why is setTimeout(fn, 0) sometimes useful?)

I've recently run into a rather nasty bug, wherein the code was loading a <select> dynamically via JavaScript.

(我最近遇到了一个令人讨厌的错误,该错误代码是通过JavaScript动态加载<select> 。)

This dynamically loaded <select> had a pre-selected value.

(动态加载的<select>具有预先选择的值。)

In IE6, we already had code to fix the selected <option> , because sometimes the <select> 's selectedIndex value would be out of sync with the selected <option> 's index attribute, as below:

(在IE6中,我们已经有代码来修复选定的<option> ,因为有时<select>selectedIndex值将与选定的<option>index属性不同步,如下所示:)

field.selectedIndex = element.index;

However, this code wasn't working.

(但是,此代码无法正常工作。)

Even though the field's selectedIndex was being set correctly, the wrong index would end up being selected.

(即使正确设置了字段的selectedIndex ,也将最终选择错误的索引。)

However, if I stuck an alert() statement in at the right time, the correct option would be selected.

(但是,如果我在正确的时间插入了alert()语句,则将选择正确的选项。)

Thinking this might be some sort of timing issue, I tried something random that I'd seen in code before:

(考虑到这可能是某种时序问题,我尝试了一些以前在代码中看到的随机现象:)

var wrapFn = (function() {
    var myField = field;
    var myElement = element;

    return function() {
        myField.selectedIndex = myElement.index;
    }
})();
setTimeout(wrapFn, 0);

And this worked!

(这有效!)

I've got a solution for my problem, but I'm uneasy that I don't know exactly why this fixes my problem.

(我已经为我的问题找到了解决方案,但是我不知道自己到底为什么能解决我的问题,对此我感到不安。)

Does anyone have an official explanation?

(有人有官方解释吗?)

What browser issue am I avoiding by calling my function "later" using setTimeout() ?

(通过使用setTimeout()调用函数“稍后”可以避免出现什么浏览器问题?)

  ask by Dan Lew translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This works because you're doing co-operative multi-tasking.

(之所以有效,是因为您正在执行协作式多任务处理。)

A browser has to do a number of things pretty much all at once, and just one of those is execute JavaScript.

(浏览器几乎必须一次完成许多事情,其中??之一就是执行JavaScript。)

But one of the things JavaScript is very often used for is to ask the browser to build a display element.

(但是JavaScript经常使用的一件事是要求浏览器构建显示元素。)

This is often assumed to be done synchronously (particularly as JavaScript is not executed in parallel) but there is no guarantee this is the case and JavaScript does not have a well-defined mechanism for waiting.

(通常认为这是同步完成的(特别是因为JavaScript不是并行执行的),但不能保证是这种情况,并且JavaScript没有明确的等待机制。)

The solution is to "pause" the JavaScript execution to let the rendering threads catch up.

(解决方案是“暂停” JavaScript执行,以使渲染线程赶上来。)

And this is the effect that setTimeout() with a timeout of 0 does.

(这就是setTimeout()的超时值为0的效果。)

It is like a thread/process yield in C. Although it seems to say "run this immediately" it actually gives the browser a chance to finish doing some non-JavaScript things that have been waiting to finish before attending to this new piece of JavaScript.

(就像C中的线程/进程产量一样。尽管似乎说“立即运行”,但实际上,它使浏览器有机会完成一些非JavaScript的事情,而这些事情在加入此新的JavaScript之前一直在等待完成。 。)

(In actuality, setTimeout() re-queues the new JavaScript at the end of the execution queue. See the comments for links to a longer explanation.)

((实际上, setTimeout()在执行队列的末尾重新排队新的JavaScript。有关更多说明的链接,请参见注释。))

IE6 just happens to be more prone to this error, but I have seen it occur on older versions of Mozilla and in Firefox.

(IE6恰好更容易出现此错误,但是我已经看到它发生在旧版本的Mozilla和Firefox中。)


See Philip Roberts talk "What the heck is the event loop?"

(参见Philip Roberts的演讲“事件循环到底是什么?”)

for more thorough explanation.

(以获得更详尽的解释。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...