- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想我会尝试聪明地创建一个我自己的 Wait 函数(我意识到还有其他方法可以做到这一点)。所以我写道:
var interval_id;
var countdowntimer = 0;
function Wait(wait_interval) {
countdowntimer = wait_interval;
interval_id = setInterval(function() {
--countdowntimer <=0 ? clearInterval(interval_id) : null;
}, 1000);
do {} while (countdowntimer >= 0);
}
// Wait a bit: 5 secs
Wait(5);
这一切都有效,除了无限循环。经检查,如果我退出 While 循环,匿名函数将按预期输入 5 次。很明显,全局变量 countdowntimer 递减了。
但是,如果我在 While 循环中检查 countdowntimer 的值,它永远不会下降。尽管在 While 循环中调用了匿名函数!
显然,不知何故,countdowntimer 有两个值 float ,但为什么呢?
编辑
好的,所以我(现在)明白 Javascript 是单线程的。那 - 有点 - 回答了我的问题。但是,在这个单线程的处理过程中,所谓的使用 setInterval 的异步调用真的发生了吗?它只是在函数调用之间吗?肯定不是,那些需要很长时间执行的函数呢?
最佳答案
周围没有变量的两个副本。 Web 浏览器中的 Javascript 单线程(除非您使用 new web workers stuff )。所以匿名函数永远没有机会运行,因为 Wait
正在占用解释器。
您不能在基于浏览器的 Javascript 中使用忙等待函数;没有其他事情会发生(在大多数其他环境中,即使它们可能发生,它们也是一个坏主意)。您必须改用回调。这是一个极简主义的改造:
var interval_id;
var countdowntimer = 0;
function Wait(wait_interval, callback) {
countdowntimer = wait_interval;
interval_id = setInterval(function() {
if (--countdowntimer <=0) {
clearInterval(interval_id);
interval_id = 0;
callback();
}
}, 1000);
}
// Wait a bit: 5 secs
Wait(5, function() {
alert("Done waiting");
});
// Any code here happens immediately, it doesn't wait for the callback
编辑 回答您的后续问题:
But, at which point in the processing of this single thread, does the so called asynchronous call using setInterval actually happen? Is it just between function calls? Surely not, what about functions that take a long time to execute?
差不多,是的 - 因此函数不要长时间运行很重要。 (从技术上讲,它甚至不在函数调用之间,因为如果您有一个调用其他三个函数的函数,则解释器在该(外部)函数运行时不能做任何其他事情。)解释器本质上维护一个它需要的函数队列执行。它首先执行任何全局代码(而不是像一个大函数调用)。然后,当事情发生时(用户输入事件,调用通过 setTimeout
安排的回调的时间到了,等等),解释器将它需要进行的调用推送到队列中。它总是在队列的前面处理调用,所以事情可以堆叠起来(比如你的 setInterval
调用,虽然 setInterval
是一个位特殊 - 如果前一个回调仍在队列中等待处理,它不会将后续回调排队)。因此,请考虑您的代码何时获得控制权以及何时释放控制权(例如,通过返回)。解释器只能在您释放控制权之后和再次将控制权还给您之前做其他事情。同样,在某些浏览器(例如 IE)上,同一个线程也用于绘制 UI 等,因此 DOM 插入(例如)不会显示,直到您将控制权交还给浏览器以便它可以获取继续绘画。
当在网络浏览器中使用 Javascript 时,您确实需要采用事件驱动的方法来设计和编码您的解决方案。典型的例子是提示用户输入信息。在非事件驱动的世界中,您可以这样做:
// Non-functional non-event-driven pseudo-example
askTheQuestion();
answer = readTheAnswer(); // Script pauses here
doSomethingWithAnswer(answer); // This doesn't happen until we have an answer
doSomethingElse();
这在事件驱动的世界中行不通。相反,你这样做:
askTheQuestion();
setCallbackForQuestionAnsweredEvent(doSomethingWithAnswer);
// If we had code here, it would happen *immediately*,
// it wouldn't wait for the answer
因此,例如,askTheQuestion
可能会在页面上覆盖一个 div,其中包含提示用户输入各种信息的字段,并在用户完成后单击“确定”按钮。 setCallbackForQuestionAnswered
实际上是 Hook “确定”按钮上的 click
事件。 doSomethingWithAnswer
将从字段中收集信息,删除或隐藏 div,并对信息做一些事情。
关于Javascript 匿名函数和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2857945/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!