BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / www-technology / #5487同步于 2008/12/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
WWWTechnology机器人发帖

[合集] [讨论] 浏览器运行脚本的流程

tntzwz
2008/12/21镜像同步0 回复
☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Tue Sep 2 19:06:00 2008) 提到: html 中的脚本总能看到对用户的一些动作会做及时的反应,比如onblur,onclick之类的。 是用户触发了一个动作,就新开一个javascript的解释流去执行?还是说所有触发的操作会在 javascript 解释器这里排个队一个一个走?有没有官方的解释? 我做过一个实验,代码如下: var flag = true; <form onsubmit='return check();'> <input type='text' onblur='change()'> <input type='submit'> ...... function change() { flag = false; } function check() { return flag; } 测试流程如下: 将鼠标置于text框中,然后点击submit按钮。 结果: 1. 如果代码在全速运行状态,表单无法提交。 2. 如果在change()函数中,加入断点,表单可提交。 分析: 两个动作触发了两个完全不同的结果。所以两个动作的脚本执行流是独立的,而不是排队等待。 问题: 1. 好像回到了经典的 C 里面的数据互斥的问题,javascript中有没有方便的语言设施提供? 2. 这样的代码出现在大量的网页中,尤其是ajax那么火,这种多个事件触发的例子更是常见。就算是全速运行,如果change()函数的执行时间超过了一定的限度,这就是个 bug 了。有无方法能够保证函数的执行顺序? ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Wed Sep 3 11:36:20 2008) 提到: 可以啊。。。。 我ie6,7,, ff2,3 都可以 ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Wed Sep 3 11:57:50 2008) 提到: 你说的可以啊,是什么意思? 不明白。 什么可以? ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Wed Sep 3 12:07:51 2008) 提到: 结果: 1. 如果代码在全速运行状态,表单无法提交。 可以。。。 我用firebug console出事件,为blur, submit 2. 如果在change()函数中,加入断点,表单可提交。 ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Wed Sep 3 13:08:30 2008) 提到: 那你的意思就是,还是在javascript解释器那里排队了? ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Wed Sep 3 13:30:24 2008) 提到: 这个顺序问题有很多文章阐述,你可以百度一下 【 在 ericyosho 的大作中提到: 】 : 那你的意思就是,还是在javascript解释器那里排队了? ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Wed Sep 3 14:53:23 2008) 提到: 我现在关心的问题并不是事件的触发顺序,这个肯定有顺序要求的。 我现在关心的是,后触发的任务是不是一定要等先触发的任务完成以后才会执行。 所以才会提到多个执行流。 【 在 diysimon 的大作中提到: 】 : 这个顺序问题有很多文章阐述,你可以百度一下 ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Wed Sep 3 15:38:37 2008) 提到: 再晕一下,最近问问题,总被人误解,看来要改变一下提问方式了,咔咔。 补充一下,既然是先触发了blur,然后才是submit,那为什么还能正常提交了呢?那不是很奇怪么? 【 在 diysimon 的大作中提到: 】 : 结果: : 1. 如果代码在全速运行状态,表单无法提交。 可以。。。 : 我用firebug console出事件,为blur, submit : ................... ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Wed Sep 3 22:59:17 2008) 提到: 呵呵,,可能我理解能力有问题~~ 你那个blur和submit有冲突吗?没有看见你那有什么代码限制submit啊 【 在 ericyosho 的大作中提到: 】 : 再晕一下,最近问问题,总被人误解,看来要改变一下提问方式了,咔咔。 : : 补充一下,既然是先触发了blur,然后才是submit,那为什么还能正常提交了呢?那不是很奇怪么? ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Thu Sep 4 00:08:13 2008) 提到: 1. 当 check() 返回 true 时,会正常跳转页面;当返回 false 时,就不跳转。(action那里我故意跳到一个不存在的页面)。 这个应该没有什么问题。 2. 现在我 check() 唯一做的事,就是返回 flag 这个变量。所以共享的变量flag如果为true就会跳转,如果为false,就不跳转。 3. 我的 flag 一开始是true,在change() 里面,把 flag 置为了 false。 我知道,当我的鼠标离开文本框,去点击submit按钮的时候,肯定是先触发 onblur=change(),再触发 onsubmit=return check()。这个在你的firefox里面也得到了证实。 4. 问题就在于,当程序全速运行的时候,change() 把flag变成false,自然就应该不能跳转了。这个和我的测试结果相同,和你的矛盾。 但是当change() 被设置为断点了以后,却可以跳转。 5. 我们假设后触发的事件,必须等先触发的完成后才能执行,那么 check() 必须在 change() 完成后才能执行,然而 change() 被断点阻塞了,所以check() 根本就不会执行,所以也就不会跳转了。但实际测试结果是跳转了,所以推测,当来了新的触发事件,不用等待前面的事件完成,而是直接有新的执行流。 6. 反过来说,当全速运行时,由于change() 很简单,所以当check() 开始执行的时候,flag已经被修改为false了,所以不会跳转。但是万一change() 的运行时间变大,当check() 开始执行的时候,flag 还没有来得及被变为false,页面就会跳转。有没有办法解决这种不正常的现象。 【 在 diysimon 的大作中提到: 】 : 呵呵,,可能我理解能力有问题~~ : 你那个blur和submit有冲突吗?没有看见你那有什么代码限制submit啊 ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Thu Sep 4 11:41:33 2008) 提到: 我终于懂了你要说的了。。。 先在组里讨论一下 ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Thu Sep 4 11:52:46 2008) 提到: 6. 反过来说,当全速运行时,由于change() 很简单,所以当check() 开始执行的时候,flag已经被修改为false了,所以不会跳转。但是万一change() 的运行时间变大,当check() 开始执行的时候,flag 还没有来得及被变为false,页面就会跳转。有没有办法解决这种不正常的现象。 这个我试了,写了个很长的循环,不会跳转 你看看下面这两个程序的执行顺序 <html> <body> <script type="text/javascript"> function a() { console.log("a is called"); var len = 10000000, j = 0; for (var i = 0; i < len; i++) { j++ } console.log("a is finished"); } function b() { console.log("b is called"); var len = 10000000, j = 0; for (var i = 0; i < len; i++) { j++ } console.log("b is finished"); } </script> <input type='text' onblur='a()'> <button onclick="b()">Click</button> </body> </html> ------------------------------------------------------------------------------------------------ <html> <body> <script type="text/javascript"> function a() { console.log("a is called"); alert(1); console.log("a is finished"); } function b() { console.log("b is called"); alert(2); console.log("b is finished"); } </script> <input type='text' onblur='a()'> <button onclick="b()">Click</button> </body> </html> ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Thu Sep 4 12:22:39 2008) 提到: 嗯,从console里面的调用顺序看,确实是会排队的,就是执行完一个再执行第二个。 现在就搞不明白了,为什么设断点的时候,就可以跳转出去了。 ☆─────────────────────────────────────☆ diysimon (I'm Forain) 于 (Thu Sep 4 13:35:35 2008) 提到: 难道是alert(可能还有confirm,prompt)的时候,相当于当前函数置入空闲,这个时候允许别的函数开始执行,直到这个函数执行完毕。 但是奇怪的是alert那段代码,先alert的是后开始的函数。。。。 baidu,google半天也找不到有人有相关的介绍 【 在 ericyosho 的大作中提到: 】 : 嗯,从console里面的调用顺序看,确实是会排队的,就是执行完一个再执行第二个。 : 现在就搞不明白了,为什么设断点的时候,就可以跳转出去了。 ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Thu Sep 4 14:12:49 2008) 提到: 嗯,我觉得在 FF 里面,确实,有alert confirm或者prompt的时候,就交到其他事件处理程序里面去了。 还有一个问题,console打印出来的就是严格的顺序么?不一定吧,这个和输出缓存有关。 另外,你上面那段 alert 的代码,在IE7里面,只响应了一个。
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。