电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

詳解JavaScript Alert函數(shù)執(zhí)行順序問題

瀏覽:103日期:2023-09-28 18:46:25
目錄問題分析解決替換 Alert() 函數(shù)setTimeOut函數(shù)小結(jié)問題

前幾天使用 JavaScript 寫 HTML 頁面時(shí)遇到了一個(gè)奇怪的問題:

我想實(shí)現(xiàn)的功能是通過 confirm() 彈窗讓用戶選擇不同的需求,每次選擇后都將選擇結(jié)果暫時(shí)輸出到頁面上,最后一次選擇結(jié)束后再一次性將選項(xiàng)傳到后端處理。 代碼類似于:

var step1 = confirm('exec step1?');$(’#result’).html($(’#result’).html() + 'n' + step1);var step2 = confirm('exec step2?');$(’#result’).html($(’#result’).html() + 'n' + step2);var step3 = confirm('exec step3?');$(’#result’).html($(’#result’).html() + 'n' + step3);send(step1, step2, step3);

可是代碼運(yùn)行后卻發(fā)現(xiàn):每次在執(zhí)行完 confirm 函數(shù),用戶選擇選項(xiàng)之后,頁面并沒有刷新,step1, step2 的結(jié)果沒有實(shí)時(shí)刷新到頁面上,而是到最后一步跟 step3 一塊顯示了出來。

后續(xù)嘗試了 alert() 和 prompt() 這兩個(gè)跟 confirm 類似的彈對(duì)話框函數(shù),情況都與此相同,它們都會(huì)跳過頁面渲染先被執(zhí)行。

此時(shí),還有更詭異的情況,我們給某一個(gè) div 里賦值后,立刻 alert 此 div 里的內(nèi)容,會(huì)發(fā)現(xiàn) alert 顯示正確的內(nèi)容,而 div 里的內(nèi)容卻沒有更新,并且會(huì)一直阻塞到我們點(diǎn)擊確定。

如圖:

詳解JavaScript Alert函數(shù)執(zhí)行順序問題

alert、prompt、confirm 三個(gè)函數(shù)都類似,接下來我們就用最簡單的 alert 來說。

分析

解決這個(gè)問題之前先了解一下它是怎么導(dǎo)致的,而要了解它需要從 JavaScript 的線程模型說起。

JavaScript 引擎是單線程運(yùn)行的,瀏覽器無論在什么時(shí)候都只且只有一個(gè)線程在運(yùn)行 JavaScript 程序,初衷是為了減少 DOM 等共享資源的沖突。可是單線程永遠(yuǎn)會(huì)面臨著一個(gè)問題,那就是某一段代碼阻塞會(huì)導(dǎo)致后續(xù)所有的任務(wù)都延遲。又由于 JavaScript 經(jīng)常需要操作頁面 DOM 和發(fā)送 HTTP 請(qǐng)求,這些 I/O 操作耗時(shí)一般都比較長,一旦阻塞,就會(huì)給用戶非常差的使用體驗(yàn)。

于是便有了事件循環(huán)(event loop)的產(chǎn)生,JavaScript 將一些異步操作或 有I/O 阻塞的操作全都放到一個(gè)事件隊(duì)列,先順序執(zhí)行同步 CPU代碼,等到 JavaScript 引擎沒有同步代碼,CPU 空閑下來再讀取事件隊(duì)列的異步事件來依次執(zhí)行。

這些事件包括:

setTimeout() 設(shè)置的異步延遲事件; DOM 操作相關(guān)如布局和繪制事件; 網(wǎng)絡(luò) I/O 如 AJAX 請(qǐng)求事件; 用戶操作事件,如鼠標(biāo)點(diǎn)擊、鍵盤敲擊。解決

明白了原理, 再解決這個(gè)問題就有了方向,我們來分析這個(gè)問題:

1.由于頁面渲染是 DOM 操作,會(huì)被 JavaScript 引擎放入事件隊(duì)列;

2.alert() 是 window 的內(nèi)置函數(shù),被認(rèn)為是同步 CPU代碼;

3.JavaScript 引擎會(huì)優(yōu)先執(zhí)行同步代碼,alert 彈窗先出現(xiàn);

4.alert 有特殊的阻塞性質(zhì),JavaScript 引擎的執(zhí)行被阻塞住;

5.點(diǎn)擊 alert 的“確定”,JavaScript 沒有了阻塞,執(zhí)行完同步代碼后,又讀取事件隊(duì)列里的 DOM 操作,頁面渲染完成。

由上述原因,導(dǎo)致了詭異的 “Alert執(zhí)行順序問題”。 我們無法將頁面渲染變成同步操作,那么只好把 alert() 變?yōu)楫惒酱a,從而才能在頁面渲染之后執(zhí)行。

對(duì)于這個(gè)解決方向,我們有兩種方法可以使用:

替換 Alert() 函數(shù)

首先我們考慮替換掉 alert 函數(shù)的功能。其實(shí)大多數(shù)情況下我們替換掉 alert 并不是它不符合我們期待的執(zhí)行順序,而是因?yàn)樗鼘?shí)在是太丑了,而且也不支持各種美化,可以想像在一個(gè)某一特定主題的網(wǎng)站上忽然彈出來一個(gè)灰色單調(diào)的對(duì)話框是多么不和諧。

這個(gè)我們可以考慮 Bootstrap 的 modal 模塊,Bootstrap 在絕大多數(shù)網(wǎng)站上都在應(yīng)用,而多引入一個(gè) modal 模塊也不會(huì)有多大影響。我們使用 modal 構(gòu)造一個(gè)彈出對(duì)話框的樣子,使用 modal 的 modal(’toggle’)/modal(’show’)/modal(’hide’) 方法可以很方便地控制 modal 的顯隱。

替換掉對(duì)話框后,我們還需要解決后續(xù)代碼執(zhí)行的問題。使用 alert 函數(shù)時(shí),我們點(diǎn)擊確定后代碼還會(huì)繼續(xù)執(zhí)行,而使用我們自定義的對(duì)話框可沒有這種功能了,需要考慮把后續(xù)代碼綁定在對(duì)話框的點(diǎn)擊按鈕上,這就需要使用 DOM 的 onclick 屬性了,我們將后續(xù)函數(shù)內(nèi)容抽出一個(gè)新的函數(shù),在彈出對(duì)話框后將這個(gè)函數(shù)綁定在按鈕的 onclick 事件上即可。

這里還需要注意,新函數(shù)內(nèi)應(yīng)該包括關(guān)閉 modal 對(duì)話框的內(nèi)容。

當(dāng)然,我們還可以再優(yōu)化一下,抽象出來一個(gè)用來彈出對(duì)話框的函數(shù)替代 alert 函數(shù),示例如下:

window.alert = function (message, callbackFunc) { $(’#alertContent’).html(message); $(’#modal’).show(); $(’#confirmButton’).onclick(function () {$(’#modal’).hide();callbackFunc(); });};

如此,我們?cè)谛枰獜棾隹驎r(shí)調(diào)用新的 alert 函數(shù),并傳入 callbackFunc ,在里面做后續(xù)的事情就可以了。

setTimeOut函數(shù)

當(dāng)然,并不是所有人都愿意使用新的對(duì)話框替換 alert 函數(shù)的對(duì)話框,總感覺上面的方法不是特別的優(yōu)雅,對(duì)此,我們可以采用另外的方法解決這個(gè)問題。

前端的同學(xué)應(yīng)該對(duì) setTimeout() 這個(gè)函數(shù)不陌生,使用它,可以延遲執(zhí)行某些代碼。而對(duì)于延遲執(zhí)行的代碼,JavaScript 引擎總是把這些代碼放到事件隊(duì)列里去,再去檢查是否已經(jīng)到了執(zhí)行時(shí)間,再適時(shí)執(zhí)行。代碼進(jìn)入事件隊(duì)列,就意味著代碼變成和頁面渲染事件一樣異步了。由于事件隊(duì)列是有序的,我們?nèi)绻?setTimeout 延時(shí)執(zhí)行,就可以實(shí)現(xiàn)在頁面渲染之后執(zhí)行 alert 的功能了。

setTimeout 的函數(shù)原型為 setTimeout(code, msec),code 是要變?yōu)楫惒降拇a或函數(shù),msec 是要延時(shí)的時(shí)間,單位為毫秒。這里我們不需要它延時(shí),只需要它變?yōu)楫惒骄托辛耍钥梢詫?msec 設(shè)置為 0;

同樣,alert 之后的代碼我們也需要處理,將它們跟 alert 一塊放到 setTimeout 里異步執(zhí)行。這樣,代碼就變?yōu)?setTimeout('alert(’msg’);doSomething();', 0);,如果覺得代碼不夠美觀或字符串不好處理的話,可以將后續(xù)代碼封裝成一個(gè)函數(shù)放到 doSomething() 里即可。

小結(jié)

在上面的兩個(gè)解決方案中,都利用了 JavaScript 的回調(diào)函數(shù),前者將函數(shù)所為 alert 的參數(shù)并綁定到 DOM 的 onclick 事件,后者使用 setTimeout 將函數(shù)轉(zhuǎn)為異步執(zhí)行。JavaScript 的回調(diào)函數(shù)確實(shí)非常強(qiáng)大,使用起來也很簡單,但是卻有一個(gè)隱含的問題,就是回調(diào)嵌套問題,單層的回調(diào)很容易理解,但如果要實(shí)現(xiàn)像我的需求一樣,有多個(gè) alert 和頁面渲染輪流執(zhí)行的情況,需要面臨的可能就是“回調(diào)地獄”, onclick 事件綁定里的函數(shù)又要嵌套綁定 onclick 函數(shù), setTimeout 里還需要另一個(gè) setTimeout 語句,一旦出現(xiàn)問題,排查起來就比較麻煩了。

以上就是詳解JavaScript Alert函數(shù)執(zhí)行順序問題的詳細(xì)內(nèi)容,更多關(guān)于JavaScript Alert函數(shù)執(zhí)行順序問題的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 破碎机_上海破碎机_破碎机设备_破碎机厂家-上海山卓重工机械有限公司 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 帽子厂家_帽子工厂_帽子定做_义乌帽厂_帽厂_制帽厂_帽子厂_浙江高普制帽厂 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | (中山|佛山|江门)环氧地坪漆,停车场地板漆,车库地板漆,聚氨酯地板漆-中山永旺地坪漆厂家 | 培训中心-海南香蕉蛋糕加盟店技术翰香原中心官网总部 | 造价工程师网,考试时间查询,报名入口信息-网站首页 | 真空搅拌机-行星搅拌机-双行星动力混合机-广州市番禺区源创化工设备厂 | EPDM密封胶条-EPDM密封垫片-EPDM生产厂家 | 浙江栓钉_焊钉_剪力钉厂家批发_杭州八建五金制造有限公司 | 聚天冬氨酸,亚氨基二琥珀酸四钠,PASP,IDS - 远联化工 | 环比机械| 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 顺景erp系统_erp软件_erp软件系统_企业erp管理系统-广东顺景软件科技有限公司 | 天助网 - 中小企业全网推广平台_生态整合营销知名服务商_天助网采购优选 | 执业药师报名条件,考试时间,考试真题,报名入口—首页 | 浩方智通 - 防关联浏览器 - 跨境电商浏览器 - 云雀浏览器 | 交通信号灯生产厂家_红绿灯厂家_电子警察监控杆_标志杆厂家-沃霖电子科技 | Q361F全焊接球阀,200X减压稳压阀,ZJHP气动单座调节阀-上海戎钛 | 河南不锈钢水箱_地埋水箱_镀锌板水箱_消防水箱厂家-河南联固供水设备有限公司 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 | 荣事达手推洗地机_洗地机厂家_驾驶式扫地机_工业清洁设备 | 丹尼克尔拧紧枪_自动送钉机_智能电批_柔性振动盘_螺丝供料器品牌 | 软装设计-提供软装装饰和软装配饰及软装陈设的软装设计公司 | 济南冷库安装-山东冷库设计|建造|冷库维修-山东齐雪制冷设备有限公司 | 光纤测温-荧光光纤测温系统-福州华光天锐光电科技有限公司 | 陕西高职单招-陕西高职分类考试网| 福州甲醛检测-福建室内空气检测_环境检测_水质检测-福建中凯检测技术有限公司 | 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | 等离子空气净化器_医用空气消毒机_空气净化消毒机_中央家用新风系统厂家_利安达官网 | 隧道烘箱_隧道烘箱生产厂家-上海冠顶专业生产烘道设备 | 污水处理设备,一体化泵站,一体化净水设备-「梦之洁环保设备厂家」 | 成都治疗尖锐湿疣比较好的医院-成都治疗尖锐湿疣那家医院好-成都西南皮肤病医院 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 依维柯自动挡房车,自行式国产改装房车,小型房车价格,中国十大房车品牌_南京拓锐斯特房车 - 南京拓锐斯特房车 | 华禹护栏|锌钢护栏_阳台护栏_护栏厂家-华禹专注阳台护栏、楼梯栏杆、百叶窗、空调架、基坑护栏、道路护栏等锌钢护栏产品的生产销售。 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | VI设计-LOGO设计公司-品牌设计公司-包装设计公司-导视设计-杭州易象设计 |