浠庝竴閬撻潰璇曢璋堣皥瀵?EventLoop 鐨勭悊瑙?/h1> Posted 鍓嶇璇曠偧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浠庝竴閬撻潰璇曢璋堣皥瀵?EventLoop 鐨勭悊瑙?/h1>
相关的知识,希望对你有一定的参考价值。
鍓嶈█
鍥犱负鎺橀噾鏀圭増涔嬪悗瀵逛簬瀛楁暟鏈変簡涓€瀹氱殑闄愬埗锛堜翰娴嬩簡涓嬪湪12500瀛楀乏鍙筹紝鎵€浠ョ湅鍒版爣棰樿繕鏈夊嚑涓囧瓧闀挎枃鐨勬爣棰樹竴瀹氭槸鍦ㄥ敩浣犵殑馃槀锛夋枃绔犵編鍖栨帓鐗堜箣鍚庡瓧鏁拌秴鍑轰簡闄愬埗鎵€浠ユ墦绠楀皢鍚庨潰鐨勯儴鍒嗗崟鐙嫀鍑烘潵鍐? 杩欐牱涔熸洿濂界殑鍐欏嚭鐩稿姣旇緝娣卞叆鐨勪竴鐐圭殑鍐呭, 瀵逛簬銆愬墠绔綋绯汇€?/code>杩欑被鏂囩珷鍐呭涓€瀹氭槸鍖呮嫭浣嗕笉闄愪簬鏍囬鐨勶紝鎴戜細灏藉彲鑳界殑鎷撳睍銆佹繁鍏ャ€佷互鍐欏嚭楂樿川閲忕殑濂芥枃绔犮€?/p>
鍦ㄧ嚎鍗戝井锛屽鏋滆寰楄繖绡囨枃绔犲浣犳湁甯姪鐨勮瘽娆㈣繋澶у鐐逛釜璧烉煈?/p>
浠庝竴閬撻寮曞嚭瀵笶vent Loop鐨勬€濊€?/span>
瀵逛簬Event Loop(浜嬩欢杞锛夋墍娑夊強鐨勭煡璇嗘蹇靛お澶氫簡锛屽鏋滀笂鏉ュ氨璁蹭竴澶у爢姒傚康鎬х殑涓滆タ澶灟鐕ヤ笖浠庝竴寮€濮嬪氨鏄寜鐓ф垜鐨勬€濊矾鏉ヨ蛋鐨勶紝鎵€浠ユ垜鎵撶畻鎹竴绉嶆柟寮忔潵鍐欒繖绡囨枃绔狅紝浣犲厛鎸夌収浣犱箣鍓嶅浜嶦vent Loop(浜嬩欢杞)鐨勭悊瑙f潵瑙h繖閬撻锛屾垜鍦ㄥ悗闈㈠啓鍑烘垜浠嶦vent Loop鐨勭悊瑙f€濊€冭繖棰樼殑鏂瑰紡銆備袱绉嶄笉鍚岀殑鐞嗚В銆佹兂娉曘€佷簰鐩哥鎾烇紝鎴戝彲鑳芥湁鐞嗚В涓嶅鐨勶紝浣犱篃鍙兘鏈変箣鍓嶅拷鐣ョ殑涓€浜涚煡璇嗙偣锛屾垜浠?/p>
涓嶅ソ鎰忔€濇斁閿欎簡馃槄锛岃繖寮犲浘
锛夎繘琛屾彃鍏ユ搷浣滐紝鍜屾爤涓€鏍凤紝闃熷垪鏄竴绉嶆搷浣滃彈闄愬埗鐨勭嚎鎬ц〃銆傝繘琛屾彃鍏ユ搷浣滅殑绔О涓洪槦灏撅紝杩涜鍒犻櫎鎿嶄綔鐨勭绉颁负闃熷ご銆?nbsp;闃熷垪涓病鏈夊厓绱犳椂锛岀О涓?span>绌洪槦鍒?/strong>銆?/p>
闃熷垪鐨勬暟鎹厓绱犲張绉颁负闃熷垪鍏冪礌銆傚湪闃熷垪涓彃鍏ヤ竴涓槦鍒楀厓绱犵О涓哄叆闃燂紝浠庨槦鍒椾腑鍒犻櫎涓€涓槦鍒楀厓绱犵О涓哄嚭闃熴€傚洜涓洪槦鍒楀彧鍏佽鍦ㄤ竴绔彃鍏ワ紝鍦ㄥ彟涓€绔垹闄わ紝鎵€浠ュ彧鏈夋渶鏃╄繘鍏ラ槦鍒楃殑鍏冪礌鎵嶈兘鏈€鍏堜粠闃熷垪涓垹闄わ紝鏁呴槦鍒楀張绉颁负鍏堣繘鍏堝嚭锛?code class="mq-110">FIFO: first-in-first-out锛?/p>
js涓殑鍫嗘爤闃熷垪
涓嬮潰鎴戣В閲婁笅JavaScript璇█涓殑鍫嗐€佹爤銆侀槦鍒椼€?/p>
鍫?/strong>
鍫嗭紝 鍔ㄦ€佸垎閰嶇殑鍐呭瓨锛屽ぇ灏忎笉瀹氫篃涓嶄細鑷姩閲婃斁锛屽瓨鏀?span>寮曠敤绫诲瀷锛屾寚閭d簺鍙兘鐢卞涓€兼瀯鎴愮殑瀵硅薄锛屼繚瀛樺湪鍫嗗唴瀛樹腑锛屽寘鍚紩鐢ㄧ被鍨嬬殑鍙橀噺锛屽疄闄呬笂淇濆瓨鐨勪笉鏄彉閲忔湰韬紝鑰屾槸鎸囧悜璇ュ璞$殑鎸囬拡銆傚彲浠ョ畝鍗曠悊瑙d负瀛樺偍浠g爜鍧椼€?/p>
鍫嗙殑浣滅敤锛氬瓨鍌ㄥ紩鐢ㄧ被鍨嬪€肩殑鏁版嵁
let obj = {
name: '鍖楁瓕'锛?br> puslic: '鍓嶇鑷椹跨珯'
}
let func = () => {
console.log('hello world')
}
鏍?/strong>
js涓殑鏍堝噯纭潵灏嗗簲璇ュ彨璋冪敤鏍?EC Stack)锛屼細鑷姩鍒嗛厤鍐呭瓨绌洪棿锛屼細鑷姩閲婃斁锛屽瓨鏀?span>鍩烘湰绫诲瀷锛岀畝鍗曠殑鏁版嵁娈碉紝鍗犳嵁鍥哄畾澶у皬鐨勭┖闂淬€?/p>
鏍堢殑浣滅敤锛氬瓨鍌ㄥ熀鏈被鍨嬪€硷紝杩樻湁涓€涓緢瑕佺殑浣滅敤銆?span>鎻愪緵浠g爜鎵ц鐨勭幆澧?/strong>
闃熷垪
js涓殑闃熷垪鍙互鍙仛浠诲姟闃熷垪鎴?span>寮傛闃熷垪锛屼换鍔¢槦鍒楅噷瀛樻斁鍚勭寮傛鎿嶄綔鎵€娉ㄥ唽鐨勫洖璋冿紝閲岄潰鍒嗕负涓ょ浠诲姟绫诲瀷锛屽畯浠诲姟(macroTask
)鍜屽井浠诲姟(microTask
)銆?/p>
濂斤紝涓嬮潰鍙互鍥炲埌姝i涓婃潵浜嗐€?/p>
涓轰粈涔堜細鍑虹幇Event Loop
鎬绘墍鍛ㄧ煡JS鏄竴闂ㄥ崟绾跨▼鐨勯潪闃诲鑴氭湰璇█锛孍vent Loop灏辨槸涓轰簡瑙e喅JS寮傛缂栫▼鐨勪竴绉嶈В鍐虫柟妗堛€?/p>
JS涓轰粈涔堟槸鍗曠嚎绋嬭瑷€锛岄偅瀹冩槸鎬庝箞瀹炵幇寮傛缂栫▼(闈為樆濉?杩愯鐨?/span>
绗竴涓棶棰橈細JavaScript鐨勮癁鐢熷氨鏄负浜嗗鐞嗘祻瑙堝櫒缃戦〉鐨勪氦浜掞紙DOM鎿嶄綔鐨勫鐞嗐€乁I鍔ㄧ敾绛?, 璁捐鎴愬崟绾跨▼鐨勫師鍥犲氨鏄笉鎯宠娴忚鍣ㄥ彉寰楀お澶嶆潅锛屽洜涓哄绾跨▼闇€瑕佸叡浜祫婧愩€佷笖鏈夊彲鑳戒慨鏀瑰郊姝ょ殑杩愯缁撴灉锛堜袱涓嚎绋嬩慨鏀逛簡鍚屼竴涓狣OM鑺傜偣灏变細浜х敓涓嶅繀瑕佺殑楹荤儲锛夛紝杩欏浜庝竴绉嶇綉椤佃剼鏈瑷€鏉ヨ杩欏氨澶鏉備簡銆?/p>
绗簩涓棶棰橈細JavaScript鏄崟绾跨▼鐨勪絾瀹冩墍杩愯鐨勫涓荤幆澧冣€旀祻瑙堝櫒鏄绾跨▼锛屾祻瑙堝櫒鎻愪緵浜嗗悇绉嶇嚎绋嬩緵Event Loop璋冨害鏉ュ崗璋僇S鍗曠嚎绋嬭繍琛屾椂涓嶄細闃诲銆?/p>
灏忕粨
鍏堟€荤粨涓€娉釜浜哄浜嶫S杩愯鏈哄埗鐨勭悊瑙o細
浠g爜鎵ц寮€鍚竴涓叏灞€璋冪敤鏍?涓绘爤)鎻愪緵浠g爜杩愯鐨勭幆澧冿紝鍦ㄦ墽琛岃繃绋嬩腑鍚屾浠诲姟鐨勪唬鐮佺珛鍗虫墽琛岋紝閬囧埌寮傛浠诲姟灏嗗紓姝ョ殑鍥炶皟娉ㄥ唽鍒颁换鍔¢槦鍒椾腑锛岀瓑寰呭悓姝ヤ唬鐮佹墽琛屽畬姣曟煡鐪嬪紓姝ユ槸鍚﹀畬鎴愶紝濡傛灉瀹屾垚灏嗗綋鍓嶅紓姝ヤ换鍔$殑鍥炶皟鎷垮埌涓绘爤涓墽琛?/p>
杩涚▼鍜岀嚎绋?/span>
杩涚▼锛氳繘绋嬫槸 CPU 璧勬簮鍒嗛厤鐨勬渶灏忓崟浣?鏄兘鎷ユ湁璧勬簮鍜岀嫭绔嬭繍琛岀殑鏈€灏忓崟浣?
绾跨▼锛氱嚎绋嬫槸 CPU 璋冨害鐨勬渶灏忓崟浣?绾跨▼鏄缓绔嬪湪杩涚▼鐨勫熀纭€涓婄殑涓€娆$▼搴忚繍琛屽崟浣?
瀵逛簬杩涚▼鍜岀嚎绋嬪苟娌℃湁纭垏缁熶竴鐨勬弿杩帮紝鍙互绠€鍗曠殑鐞嗚В锛?/p>
姣斿涓€涓簲鐢ㄧ▼搴? 濡俀Q銆佹祻瑙堝櫒鍚姩鏃朵細寮€鍚竴涓繘绋嬶紝鑰岃杩涚▼鍙互鏈夊涓嚎绋嬫潵杩涜璧勬簮璋冨害鍜屽垎閰嶏紝杈惧埌杩愯绋嬪簭鐨勪綔鐢ㄣ€?/p>
鏇撮€氫織鐨勮瘽璁诧細鎵撳紑QQ搴旂敤绋嬪簭寮€鍚簡杩涚▼鏉ヨ繍琛岀▼搴?QQ), 鏈夊涓嚎绋嬫潵杩涜璧勬簮璋冨害鍜屽垎閰?澶氫釜绾跨▼鏉ュ垎閰嶆墦寮€QQ鎵€鍗犵敤鐨勮繍瀛?锛岃揪鍒拌繍琛岀▼搴?QQ)鐨勪綔鐢?
鐢ㄦ搷浣滅郴缁熸潵浣滀釜渚嬪瓙锛?/p>
绾跨▼渚濊禆杩涚▼锛屼竴涓繘绋嬪彲浠ユ湁涓€涓垨鑰呭涓嚎绋嬶紝浣嗘槸绾跨▼鍙兘鏄睘浜庝竴涓繘绋嬨€?/p>
JS鐨勫崟绾跨▼
js鐨勫崟绾跨▼鎸囩殑鏄痡avaScript寮曟搸鍙湁涓€涓嚎绋?/p>
鍗曠嚎绋嬪氨鎰忓懗鐫€锛屾墍鏈変换鍔¢渶瑕佹帓闃燂紝鍓嶄竴涓换鍔$粨鏉燂紝鎵嶄細鎵ц鍚庝竴涓换鍔°€傚鏋滃墠涓€涓换鍔¤€楁椂寰堥暱锛屽悗涓€涓换鍔″氨涓嶅緱涓嶄竴鐩寸瓑鐫€銆俲s 寮曟搸鎵ц寮傛浠g爜鑰屼笉鐢ㄧ瓑寰咃紝鏄洜鏈変负鏈変换鍔¢槦鍒楀拰浜嬩欢杞銆?/p>
-
浠诲姟闃熷垪锛氫换鍔¢槦鍒楁槸涓€涓厛杩涘厛鍑虹殑闃熷垪锛屽畠閲岄潰瀛樻斁鐫€鍚勭浠诲姟鍥炶皟銆?
-
浜嬩欢杞锛氫簨浠惰疆璇㈡槸鎸囦富绾跨▼閲嶅浠庝换鍔¢槦鍒椾腑鍙栦换鍔°€佹墽琛屼换鍔$殑杩囩▼銆?
娴忚鍣ㄧ殑澶氱嚎绋?/span>
-
GUI 娓叉煋绾跨▼
-
缁樺埗椤甸潰锛岃В鏋?html銆丆SS锛屾瀯寤?DOM 鏍戯紝甯冨眬鍜岀粯鍒剁瓑
-
椤甸潰閲嶇粯鍜屽洖娴?
-
涓?JS 寮曟搸绾跨▼浜掓枼锛屼篃灏辨槸鎵€璋撶殑 JS 鎵ц闃诲椤甸潰鏇存柊
-
JS 寮曟搸绾跨▼
-
璐熻矗 JS 鑴氭湰浠g爜鐨勬墽琛?
-
璐熻矗鍑嗘墽琛屽噯澶囧ソ寰呮墽琛岀殑浜嬩欢锛屽嵆瀹氭椂鍣ㄨ鏁扮粨鏉燂紝鎴栧紓姝ヨ姹傛垚鍔熷苟姝g‘杩斿洖鐨勪簨浠?
-
涓?GUI 娓叉煋绾跨▼浜掓枼锛屾墽琛屾椂闂磋繃闀垮皢闃诲椤甸潰鐨勬覆鏌?
-
浜嬩欢瑙﹀彂绾跨▼
-
璐熻矗灏嗗噯澶囧ソ鐨勪簨浠朵氦缁?JS 寮曟搸绾跨▼鎵ц
-
澶氫釜浜嬩欢鍔犲叆浠诲姟闃熷垪鐨勬椂鍊欓渶瑕佹帓闃熺瓑寰?JS 鐨勫崟绾跨▼)
-
瀹氭椂鍣ㄨЕ鍙戠嚎绋?/p>
-
璐熻矗鎵ц寮傛鐨勫畾鏃跺櫒绫荤殑浜嬩欢锛屽 setTimeout銆乻etInterval
-
瀹氭椂鍣ㄥ埌鏃堕棿涔嬪悗鎶婃敞鍐岀殑鍥炶皟鍔犲埌浠诲姟闃熷垪鐨勯槦灏?
-
HTTP 璇锋眰绾跨▼
-
璐熻矗鎵ц寮傛璇锋眰
-
涓荤嚎绋嬫墽琛屼唬鐮侀亣鍒板紓姝ヨ姹傜殑鏃跺€欎細鎶婂嚱鏁颁氦缁欒绾跨▼澶勭悊锛屽綋鐩戝惉鍒扮姸鎬佸彉鏇翠簨浠讹紝濡傛灉鏈夊洖璋冨嚱鏁帮紝璇ョ嚎绋嬩細鎶婂洖璋冨嚱鏁板姞鍏ュ埌浠诲姟闃熷垪鐨勯槦灏剧瓑寰呮墽琛?
Event Loop
鍛硷紝缁堜簬鍥炲埌姝i浜嗭紒
瀵逛簬浜嬩欢杞涓婇潰鍏跺疄宸茬粡瑙i噴鐨勫緢娓呮浜嗭細
浜嬩欢杞灏辨槸瑙e喅javascript鍗曠嚎绋嬪浜庡紓姝ユ搷浣滅殑涓€浜涚己闄凤紝璁?javaScript鍋氬埌鏃㈡槸鍗曠嚎绋?/strong>锛屽張缁濆涓嶄細闃诲鐨勬牳蹇冩満鍒讹紝鏄敤鏉ュ崗璋冨悇绉嶄簨浠躲€佺敤鎴蜂氦浜掋€佽剼鏈墽琛屻€乁I 娓叉煋銆佺綉缁滆姹傜瓑鐨勪竴绉嶆満鍒躲€?/p>
娴忚鍣ㄤ腑鐨凟veent Loop鎵ц椤哄簭
Processing model[1]瑙勮寖瀹氫箟浜?code class="mq-225">Eveent Loop鐨勫惊鐜繃绋嬶細
涓€涓狤veent Loop鍙瀛樺湪锛屽氨浼氫笉鏂墽琛屼笅杈圭殑姝ラ锛?/p>
-
1.鍦╰asks(浠诲姟)闃熷垪涓€夋嫨鏈€鑰佺殑涓€涓猼ask,鐢ㄦ埛浠g悊鍙互閫夋嫨浠讳綍task闃熷垪锛屽鏋滄病鏈夊彲閫夌殑浠诲姟锛屽垯璺冲埌涓嬭竟鐨刴icrotasks姝ラ銆?
-
2.灏嗕笂杈归€夋嫨鐨則ask璁剧疆涓?
姝e湪杩愯鐨則ask
[2]銆?
-
3.Run: 杩愯琚€夋嫨鐨則ask銆?
-
4.灏咵veent Loop鐨?
currently running task
[3]鍙樹负null銆?
-
5.浠巘ask闃熷垪閲岀Щ闄ゅ墠杈硅繍琛岀殑task銆?
-
6.Microtasks: 鎵ц
microtasks浠诲姟妫€鏌ョ偣
[4]銆傦紙涔熷氨鏄墽琛宮icrotasks闃熷垪閲岀殑浠诲姟锛?
-
7.鏇存柊娓叉煋锛圲pdate the rendering锛夛細鍙互绠€鍗曠悊瑙d负娴忚鍣ㄦ覆鏌?..
-
8.濡傛灉杩欐槸涓€涓獁orker event loop锛屼絾鏄病鏈変换鍔″湪task闃熷垪涓紝骞朵笖
WorkerGlobalScope
[5]瀵硅薄鐨刢losing鏍囪瘑涓簍rue锛屽垯閿€姣丒veent Loop锛屼腑姝㈣繖浜涙楠わ紝鐒跺悗杩涜瀹氫箟鍦?
Web workers
[6]绔犺妭鐨?
run a worker
[7]銆?
-
9.杩斿洖鍒扮涓€姝ャ€?
Eveent Loopp浼氫笉鏂惊鐜笂闈㈢殑姝ラ锛屾鎷鏉ワ細
-
Eveent Loop
浼氫笉鏂惊鐜殑鍘诲彇
tasks
闃熷垪鐨勪腑鏈€鑰佺殑涓€涓猼ask(鍙互鐞嗚В涓哄畯浠诲姟锛夋帹鍏ユ爤涓墽琛岋紝骞跺湪褰撴寰幆閲屼緷娆℃墽琛屽苟娓呯┖
microtask
闃熷垪閲岀殑浠诲姟銆?
-
鎵ц瀹?
microtask
闃熷垪閲岀殑浠诲姟锛屾湁
鍙兘浼氭覆鏌撴洿鏂般€傦紙娴忚鍣ㄥ緢鑱槑锛屽湪涓€甯т互鍐呯殑澶氭dom鍙樺姩娴忚鍣ㄤ笉浼氱珛鍗冲搷搴旓紝鑰屾槸浼氱Н鏀掑彉鍔ㄤ互鏈€楂?0HZ(澶х害16.7ms姣忓抚)鐨勯鐜囨洿鏂拌鍥撅級
瀹忎换鍔″拰寰换鍔′紭鍏堥棶棰?/span>
鍦ㄤ换鍔″鍒?queue)涓敞鍐岀殑寮傛鍥炶皟鍙堝垎涓轰袱绉嶇被鍨嬶紝瀹忎换鍔″拰寰换鍔°€傛垜浠负浜嗘柟渚跨悊瑙e彲浠ヨ涓哄湪浠诲姟闃熷垪涓湁瀹忎换鍔¢槦鍒楀拰寰换鍔¢槦鍒椼€傚畯浠诲姟闃熷垪鏈夊涓紝寰换鍔″彧鏈変竴涓?/p>
-
瀹忎换鍔?macro Task)
-
script(鏁翠綋浠g爜)
-
setTimeout/setInterval
-
setImmediate(Node鐜)
-
UI 娓叉煋
-
requestAnimationFrame
-
....
-
寰换鍔?micro Task)
-
Promise鐨則hen()銆乧atch()銆乫inally()閲岄潰鐨勫洖璋?/p>
-
process.nextTick(Node 鐜锛?/p>
-
...
涓汉鐞嗚В鐨勬墽琛岄『搴忥細
-
浠g爜浠庡紑濮嬫墽琛岃皟鐢ㄤ竴涓叏灞€鎵ц鏍堬紝script鏍囩浣滀负瀹忎换鍔℃墽琛?/p>
-
鎵ц杩囩▼涓悓姝ヤ唬鐮佺珛鍗虫墽琛岋紝寮傛浠g爜鏀惧埌浠诲姟闃熷垪涓紝浠诲姟闃熷垪瀛樻斁鏈変袱绉嶇被鍨嬬殑寮傛浠诲姟锛屽畯浠诲姟闃熷垪锛屽井浠诲姟闃熷垪銆?/p>
-
鍚屾浠g爜鎵ц瀹屾瘯涔熷氨鎰忓懗鐫€绗竴涓畯浠诲姟鎵ц瀹屾瘯(script)
-
1銆佸厛鏌ョ湅浠诲姟闃熷垪涓殑寰换鍔¢槦鍒楁槸鍚﹀瓨鍦ㄥ畯浠诲姟鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟
1-1銆佹湁鐨勮瘽灏卞皢寰换鍔¢槦鍒椾腑鐨勬墍鏈夊井浠诲姟娓呯┖
2-2銆佸井浠诲姟鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒椾腑锛屽湪姝ゆ鎵ц涓竴骞舵竻绌?/p>
-
2銆佸鏋滄病鏈夊啀鐪嬬湅瀹忎换鍔¢槦鍒椾腑鏈夋病鏈夊畯浠诲姟锛屾湁鐨勮瘽鎵ц锛屾病鏈夌殑璇濅簨浠惰疆璇㈢涓€娉㈢粨鏉?/p>
2-1銆佹墽琛岃繃绋嬩腑鎵€浜х敓鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?/p>
2-2銆佸畬鎴愬畯浠诲姟涔嬪悗鎵ц娓呯┖寰换鍔¢槦鍒楃殑浠g爜
鎵€浠ユ槸瀹忎换鍔′紭鍏堬紝鍦ㄥ畯浠诲姟鎵ц瀹屾瘯涔嬪悗鎵嶄細鏉ヤ竴娆℃€ф竻绌轰换鍔¢槦鍒椾腑鐨勬墍鏈夊井浠诲姟銆?/p>
瑙i鍒嗘瀽杩囩▼
灏嗘渶寮€濮嬬殑閭i亾棰樻惉涓嬫潵
// => 浠g爜涓€鎵ц灏卞紑濮嬫墽琛屼簡涓€涓畯浠诲姟-瀹?
console.log('script start');
setTimeout(() => { // 瀹?nbsp;1
console.log('鍖楁瓕');
}, 1 * 2000);
Promise.resolve()
.then(function() { // 寰?-1
console.log('promise1');
})
.then(function() { // 寰?-4 => 杩欎釜then涓殑浼氱瓑寰呬笂涓€涓猼hen鎵ц瀹屾垚涔嬪悗寰楀埌鍏剁姸鎬佹墠浼氬悜Queue娉ㄥ唽鐘舵€佸搴旂殑鍥炶皟锛屽亣璁句笂涓€涓猼hen涓富鍔ㄦ姏閿欎笖娌℃湁鎹曡幏锛岄偅灏辨敞鍐岀殑鏄繖涓猼hen涓殑绗簩涓洖璋冧簡銆?/span>
console.log('promise2');
});
async function foo() {
await bar() // => await(promise鐨勮娉曠硸)锛屼細寮傛绛夊緟鑾峰彇鍏惰繑鍥炲€?/span>
// => 鍚庨潰鐨勪唬鐮佸彲浠ョ悊瑙d负鏀惧埌寮傛闃熷垪寰换鍔′腑銆?nbsp;杩欓噷鍙互淇濈暀鐤戦棶鍚庨潰浼氳缁嗚
console.log('async1 end') // 寰?-2
}
foo()
function bar() {
console.log('async2 end')
}
async function errorFunc () {
try {
await Promise.reject('error!!!')
} catch(e) {
// => 浠庤繖鍚庨潰寮€濮嬫墍鏈夌殑浠g爜鍙互鐞嗚В涓烘斁鍒板紓姝ラ槦鍒楀井浠诲姟涓?/span>
console.log(e) // 寰?-3
}
console.log('async1');
return Promise.resolve('async1 success')
}
errorFunc().then(res => console.log(res)) // 寰?-5
console.log('script end');
涓婇潰浠g爜瀵逛簬Promise鐨勭敤娉曟垜灏变笉澶氳浜? 鍦ㄥ悗闈㈡垜浼氬啓鍏充簬Promise婧愮爜瑙f瀽鐨勬枃绔犮€?/p>
娉ㄦ剰涓€鐐瑰氨鏄疨romise.then().then()锛屽湪娉ㄥ唽寮傛浠诲姟鐨勬椂鍊欙紝绗簩涓猼hen涓殑鍥炶皟鏄緷璧栫涓€涓猼hen涓洖璋冪殑缁撴灉鐨勶紝濡傛灉鎵ц娌℃湁寮傚父鎵嶄細鍦ㄨ寮傛浠诲姟鎵ц瀹屾瘯涔嬪悗娉ㄥ唽鐘舵€佸搴旂殑鍥炶皟
绗竴娆℃墽琛?/span>
鍏ㄥ眬涓€涓畯浠诲姟鎵ц, 杈撳嚭鍚屾浠g爜銆傛寕杞藉畯1銆佸井1-1銆佸井1-2銆佸井1-3銆佸井1-4銆?-琛ㄧず灞炰簬绗竴娆¤疆璇?/p>
run: script start銆?nbsp;async2 end銆乻cript end
绗簩娆℃墽琛?/span>
鍚屾浠g爜鎵ц瀹屾瘯锛屽紑濮嬫墽琛屽紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪涓殑浠g爜銆?/p>
寰换鍔¢槦鍒楋細鍙湁涓€涓槦鍒椾笖浼氬湪褰撳墠杞涓€娆℃竻绌?/strong>
run:
鎵ц寰?span class="mq-390">1
-1: promise1
鎵ц寰?span class="mq-392">1
-2: async1 end
鎵ц寰?span class="mq-394">1
-3: error!!!銆乤sync1 銆傚綋鍓嶅紓姝ュ洖璋冩墽琛屽畬姣曟墠Promise.resolve('async1 success')锛岀劧鍚庢敞鍐宼hen()涓殑鎴愬姛鐨勫洖璋?寰?span class="mq-398">1-5
鎵ц寰?span class="mq-400">1-4: promise2
鎵ц鍒氬垰娉ㄥ唽鐨勫井1-5: async1 success
鍒拌繖绗竴娉㈣疆璇㈢粨鏉?/strong>
绗笁娆℃墽琛?/span>
寮€鍚浜屾尝杞锛氭墽琛屽畯1
run: '鍖楁瓕'
鍒拌繖銆傛暣涓疆璇㈢粨鏉熴€?/p>
鍏跺疄鐩稿闅句互鐞嗚В鐨勪篃灏辨槸寰换鍔★紝瀵逛簬寰换鍔′篃灏辨槸涓婇潰璇寸殑鍙湁涓€涓槦鍒椾細鍦?span>姝ゆ杞涓竴娆℃竻绌?鍖呮嫭姝ゆ鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟)銆?/p>
涓句釜鏍楀瓙馃尠
浣犲幓鍫傞鎺掗槦鎵撹彍锛屽師鏈綘璁″垝浠婂ぉ鍙悆涓や釜鑿?寰换鍔¢槦鍒椾腑鍙敞鍐屼簡涓や釜鍥炶皟)锛屽湪鎵撹彍鐨勮繃绋嬩腑浣犵湅鍒颁綘鏈€鍠滄鍚冪殑绾㈢儳鑲?寰换鍔℃墽琛岀殑杩囩▼涓亣鍒扮殑鏂扮殑寰换鍔?锛屼綘鑲畾寰楀啀鍔犱釜鑿?灏嗗井浠诲姟鍔犲叆鍒板井浠诲姟闃熷垪)
鎵撴€繘闃?/span>
閫氳繃涓婇潰鐨勮瑙g幇鍦ㄥ彲浠ュ埛鍑犻亾棰樻潵鐪嬬湅鑷繁鎾戞彙鐨勬€庝箞鏍蜂簡銆?/p>
榛勯噾棰?/span>
console.log('1');
setTimeout(() => {
console.log('2');
Promise.resolve().then(() => {
console.log('3');
})
new Promise((resolve) => {
console.log('4');
resolve();
}).then(() => {
console.log('5')
})
})
Promise.reject().then(() => {
console.log('13');
}, () => {
console.log('12');
})
new Promise((resolve) => {
console.log('7');
resolve();
}).then(() => {
console.log('8')
})
setTimeout(() => {
console.log('9');
Promise.resolve().then(() => {
console.log('10');
})
new Promise((resolve) => {
console.log('11');
resolve();
}).then(() => {
console.log('12')
})
})
鐮栫煶棰?/span>
new Promise((resolve, reject) => {
console.log(1)
resolve()
})
.then(() => {
console.log(2)
new Promise((resolve, reject) => {
console.log(3)
setTimeout(() => {
reject();
}, 3 * 1000);
resolve()
})
.then(() => {
console.log(4)
new Promise((resolve, reject) => {
console.log(5)
resolve();
})
.then(() => {
console.log(7)
})
.then(() => {
console.log(9)
})
})
.then(() => {
console.log(8)
})
})
.then(() => {
console.log(6)
})
鐜嬭€呴
Promise.resolve()
.then(() => {
console.log('promise1');
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('timer2')
resolve()
}, 0)
})
.then(async () => {
await foo();
return new Error('error1')
})
.then((ret) => {
setTimeout(() => {
console.log(ret);
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then(res => {
console.log("then: ", res)
})
.catch(err => {
console.log("catch: ", err)
})
}, 1 * 3000)
}, err => {
console.log(err);
})
.finally((res) => {
console.log(res);
throw new Error('error2')
})
.then((res) => {
console.log(res);
}, err => {
console.log(err);
})
})
.then(() => {
console.log('promise2');
})
function foo() {
setTimeout(() => {
console.log('async1');
}, 2 * 1000);
}
setTimeout(() => {
console.log('timer1')
Promise.resolve()
.then(() => {
console.log('promise3')
})
}, 0)
console.log('start');
鑽h€€鐜嬭€?/span>
涓嬮潰璁╂垜浠潵涓€璧峰仛鏈€鍚庤繖閬撻銆?/p>
async function async1() {
console.log('async1 start');
new Promise((resolve, reject) => {
try {
throw new Error('error1')
} catch(e) {
console.log(e);
}
setTimeout(() => { // 瀹?
resolve('promise4')
}, 3 * 1000);
})
.then((res) => { // 寰?-1
console.log(res);
}, err => {
console.log(err);
})
.finally(res => { // 寰?-2 // TODO娉?
console.log(res);
})
console.log(await async2()); // TODO-娉?
console.log('async1 end'); // 寰?-1 // TODO-娉?
}
function async2() {
console.log('async2');
return new Promise((resolve) => {
setTimeout(() => { // 瀹?
resolve(2)
}, 1 * 3000);
})
}
console.log('script start');
setTimeout(() => { // 瀹?
console.log('setTimeout');
}, 0)
async1();
new Promise((resolve) => {
console.log('promise1');
resolve();
})
.then(() => { // 寰?-2
console.log('promise2');
return new Promise((resolve) => {
resolve()
})
.then(() => { // 寰?-3
console.log('then 1-1')
})
})
.then(() => { // 寰?-4
console.log('promise3');
})
console.log('script end');
瑙勫畾
鐜板湪涓轰簡鏂逛究澶у鐞嗚В锛岃璁颁綇涓€涓嬭瀹氾細
-
鍒嗘瀽浠ユ瘡娆¤疆璇㈠仛涓哄垎鏋愶紝鍚屾浠g爜鍧楁槸鐩存帴杈撳嚭缁撴灉鐨?
-
寮傛浠诲姟浠g爜鍧椾腑锛岀孩鑹茶〃绀哄畯浠诲姟锛岀豢鑹茶〃绀哄井浠诲姟
-
寰?-
琛ㄧず绗竴娆¤疆璇腑鐨勫井浠诲姟闃熷垪涓殑鎵€鏈夊井浠诲姟锛?
寰?-
琛ㄧず绗簩娆★紝浠ユ绫绘帹
绗竴娆¤疆璇?/span>
script鏍囩(瀹?)鎵ц
杈撳嚭鍚屾浠g爜锛?/p>
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
鎸傝浇寮傛浠诲姟:
-() => { // 瀹?
- console.log('setTimeout');
-}
-() => { // 瀹?
- resolve('promise4')
-}
-() => { // 瀹?
- resolve(2)
-}
+() => { // 寰?-1
+ console.log('promise2');
+ return new Promise((resolve) => {
+ resolve()
+}
鍚屾浠g爜瀹屾瘯鐨勫悓鏃剁涓€涓畯浠诲姟涔熸墽琛屽畬姣曪紝寮€濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-763">1-1: promise2 -> 寰?span class="mq-765">1-2: then 1-1 -> 寰?span class="mq-769">1-3: promise3
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
+() => { // 寰?-2
+ console.log('then 1-1')
+}
+() => { // 寰?-3
+ console.log('promise3');
+}
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
娉?
杩欓噷寰楄涓€涓嬶紝寰堝浜鸿涓篴wait灏嗕唬鐮佸悓姝ュ寲鐨勬剰鎬濓紝鍏跺疄await鏄疨romise鐨勮娉曠硸锛屽唴閮ㄧ殑瀹炵幇涔熸槸渚濋潬Promise, 鍏惰癁鐢熶篃灏辨槸涓轰簡浼樺寲promise鐨則hen閾惧啓娉曪紝鐢ㄥ悓姝ョ殑鏂瑰紡缂栧啓寮傛浠g爜锛岃浠g爜鐪嬭捣鏉ユ洿绠€娲佹槑浜?await鐨勭湡瀹炴剰鎬濇槸 async wait(寮傛绛夊緟鐨勬剰鎬?await琛ㄨ揪寮忕浉褰撲簬璋冪敤鍚庨潰杩斿洖promise鐨則hen鏂规硶锛屽紓姝ワ紙绛夊緟锛夎幏鍙栧叾杩斿洖鍊笺€傚嵆 await<==>promise.then
杩欓噷鐨刟sync2鍑芥暟杩斿洖鐨凱romise涓紑鍚簡涓€涓畯浠诲姟锛宎wait寮傛绛夊緟闇€瑕佺瓑寰呭畯浠诲姟鎵ц鎵嶈兘鑾峰彇鍏惰繑鍥炲€硷紝涔熷氨鏄瀹忎换鍔′笉鎵цawait琛ㄨ揪寮忓氨鍘嬫牴涓嶈兘璋冪敤Promise鐨則hen鏂规硶
娉?
鍓嶉潰璇磋繃await琛ㄨ揪寮忓悗闈㈢殑浠g爜鍙互绠€鍗曠悊瑙d负鏀惧叆鍒板井浠诲姟涓紝浣嗘槸鍓嶉潰await 琛ㄨ揪寮忓帇鏍瑰氨娌℃湁鑾峰彇寮傛绛夊緟鐨勭粨鏋滆繖鍚庨潰鐨勪唬鐮佷粠璺冲嚭褰撳墠鎵ц鏍堝悗灏卞帇鏍规病鏈夋寕杞藉埌寮傛浠诲姟涓紝鏈変簺鏁欑▼璇寸殑await 琛ㄨ揪寮忓悗闈㈢殑浠g爜鍙互鐪嬫垚寰换鍔¢槦鍒楃殑绗竴涓繖绉嶈娉曟槸閿欒鐨勶紒
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
寰?span class="mq-796">1-1: promise2 -> 寰?span class="mq-798">1-2: then 1-1 -> 寰?span class="mq-802">1-3: promise3
绗簩娆¤疆璇?/span>
涓婇潰绗竴娉㈣疆璇㈢粨鏉燂紝寮€鍚浜屾尝杞
鎵ц绗簩涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹?span class="mq-812">2锛歴etTimeout
瀹忎换鍔℃墽琛屽畬姣曟病鏈変骇鐢熸柊鐨勫井浠诲姟锛屼篃娌℃湁浜х敓鏂扮殑瀹忎换鍔°€傜浜屾杞缁撴潫
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
瀹?锛歴etTimeout
绗笁娆¤疆璇?/span>
鎵ц绗笁涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹忎换鍔℃湰韬病鏈夎緭鍑哄暐锛屼笉杩囩‘瀹氫簡涓?span class="mq-825">Promise鐨勭姸鎬佸苟浼犻€掍簡涓?span class="mq-826">'promise4'缁欎笅涓€涓猼hen涓殑鎴愬姛鍥炶皟
瀹忎换鍔℃墽琛岃繃绋嬩腑浜х敓鐨勬柊鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?
+(res) => { // 寰?-1
+ console.log(res);
+}
瀹忎换鍔℃墽琛屽畬姣曞紑濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-838">3-1: promise4 -> 寰?span class="mq-840">3-2: undefined
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
+res => { // 寰?-2 // TODO娉?
+ console.log(res);
+}
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
寰?span class="mq-858">3-1: promise4 -> 寰?span class="mq-860">3-2: undefined
娉?
鍓嶉潰璇磋繃promise.finally()涔熸槸寰换鍔★紝finally鍙互鐞嗚В涓轰笉绠romise鐨勭姸鎬佹槸鎴愬姛鎴栧け璐ラ兘瑕佹墽琛屾垜銆備絾鏄垜涓嶆帴鍙椾换浣曠粨鏋溿€傚洜姝inally鎺ュ彈涓嶅埌杩斿洖鍊紃es涓簎ndefined
绗洓娆¤疆璇?/span>
鎵ц绗洓涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹忎换鍔℃湰韬病鏈夎緭鍑哄暐锛屼笉杩囩‘瀹氫簡涓?span class="mq-873">Promise鐨勭姸鎬佸苟浼犻€掍簡涓?span class="mq-874">2缁欎笅涓€涓猼hen涓殑鎴愬姛鍥炶皟
瀹忎换鍔℃墽琛岃繃绋嬩腑浜х敓鐨勬柊鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?
涓婇潰璇磋繃await => Promise.then(), 涓婇潰瀹忎换鍔℃墽琛屽畬姣曠‘瀹氫簡promise鐘舵€佸彲浠ュ幓鑾峰彇寮傛绛夊緟鐨勭粨鏋溿€傜浉褰撲簬杩欐牱锛歅romise.then((res) => {return res}) 鑰宎wait琛ㄨ揪寮忓悗闈㈢殑浠g爜鐩稿綋浜庡湪寮傛绛夊緟鑾峰彇缁撴灉鍚?/strong>鏀惧埌寰换鍔¢槦鍒椾腑 鐩稿綋浜庤繖鏍凤細Promise.then((res) => {return res}).finally(() => {}), 鍙湁鍦╝wait 琛ㄨ揪寮忓墠闈㈣幏鍙栧埌缁撴灉鍚庢墠浼氬湪浠g爜鎸傚湪鍒板紓姝ラ槦鍒椾腑
鍙互鍋氫釜瀹為獙灏嗕笂闈㈠紓姝ョ瓑寰呭畾鏃跺櫒鐨勫€艰瀹氫负鏇撮暱鏃堕棿锛岃繖涓椂鍊檃wait琛ㄨ揪寮忓悗闈㈢殑浠g爜鏄笉涓哄搷搴旂殑锛屽彧鏈夎幏鍙栧埌浜嗗紓姝ョ瓑寰呯殑缁撴灉锛屾墠浼氬搷搴斻€?/p>
+(res) => {return res} // 寰?-1
+() => {async1 end} // 寰?-2
瀹忎换鍔℃墽琛屽畬姣曞紑濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-887">4-1: 2 -> 寰?span class="mq-890">4-2: async1 end
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫井浠诲姟
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
寰?span class="mq-904">4-1: 2 -> 寰?span class="mq-907">4-2: async1 end
鎵€鏈夎疆璇㈠畬姣曚箣鍚庣殑瀹屾暣缁撴灉
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
寰?span class="mq-915">1-1: promise2 -> 寰?span class="mq-917">1-2: then 1-1 -> 寰?span class="mq-921">1-3: promise3
瀹?span class="mq-923">2锛歴etTimeout
寰?span class="mq-924">3-1: promise4 -> 寰?span class="mq-926">3-2: undefined
寰?span class="mq-929">4-1: 2 -> 寰?span class="mq-932">4-2: async1 end
濡傛灉浣犲洓閬撻鍏ㄥ鐨勮瘽锛岄偅涔堟伃鍠滀綘銆?/p>
鍐欏湪鏈€鍚?/span>
瀵逛簬銆愬墠绔綋绯汇€戣繖绯诲垪鐨勬枃绔犳垜鏄姳鐫€寰堣鐪燂紝寰堟兂鍐欏ソ鐨勫績鎬佺殑锛屼絾姣曠珶鎴戣繕鏄墠绔皬鐧?amp;鍐欎綔鏂颁汉锛屽鏋滄枃绔犱腑鏈夐偅鍧楀啓鐨勪笉澶ソ鎴栨湁闂娆㈣繋澶у鎸囧嚭锛屾垜涔熶細鍦ㄥ悗闈㈢殑鏂囩珷涓嶅仠淇敼銆備篃甯屾湜鑷繁杩涙鐨勫悓鏃惰兘璺熶綘浠竴璧锋垚闀裤€傚枩娆㈡垜鏂囩珷鐨勬湅鍙嬩滑涔熷彲浠ュ叧娉ㄤ竴涓?/p>
鎴戜細寰堟劅婵€绗竴鎵瑰叧娉ㄦ垜鐨勪汉銆?span>姝ゆ椂锛屽勾杞荤殑鎴戝拰浣狅紝杞昏涓婇樀锛涜€屽悗锛屽瘜瑁曠殑浣犲拰鎴戯紝婊¤浇鑰屽綊銆?/strong>
绯诲垪鏂囩珷
銆愬墠绔綋绯汇€戜粠鍦板熀寮€濮嬫墦閫犱竴搴т竾涓堥珮妤?/span>[8]
鍙傝€冩枃绔?/span>
娣卞叆鐞嗚В JavaScript Event Loop[9]
鍙傝€冭祫鏂?/span>
[1]Processing model: https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
[2]姝e湪杩愯鐨則ask: https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task
[3]currently running task: https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task
[4]microtasks浠诲姟妫€鏌ョ偣: https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
[5]WorkerGlobalScope: https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope
[6]Web workers: https://html.spec.whatwg.org/multipage/workers.html#workers
[7]run a worker: https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
[8]銆愬墠绔綋绯汇€戜粠鍦板熀寮€濮嬫墦閫犱竴搴т竾涓堥珮妤? https://juejin.im/post/6867784542338416648#comment
[9]娣卞叆鐞嗚В JavaScript Event Loop: https://zhuanlan.zhihu.com/p/34229323
浜ゆ祦璁ㄨ
濡傛灉浣犱笉鎯冲姞缇わ紝鍙槸鎯冲姞鎴戜篃鏄彲浠ョ殑銆?/p>
濡傛灉瑙夊緱杩欑瘒鏂囩珷杩樹笉閿欙紝鏉ヤ釜銆愬垎浜€佺偣璧炪€佸湪鐪嬨€戜笁杩炲惂锛岃鏇村鐨勪汉涔熺湅鍒皛
以上是关于浠庝竴閬撻潰璇曢璋堣皥瀵?EventLoop 鐨勭悊瑙?/h1>
Posted 鍓嶇璇曠偧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浠庝竴閬撻潰璇曢璋堣皥瀵?EventLoop 鐨勭悊瑙?/h1>
鍓嶈█
鍥犱负鎺橀噾鏀圭増涔嬪悗瀵逛簬瀛楁暟鏈変簡涓€瀹氱殑闄愬埗锛堜翰娴嬩簡涓嬪湪12500瀛楀乏鍙筹紝鎵€浠ョ湅鍒版爣棰樿繕鏈夊嚑涓囧瓧闀挎枃鐨勬爣棰樹竴瀹氭槸鍦ㄥ敩浣犵殑馃槀锛夋枃绔犵編鍖栨帓鐗堜箣鍚庡瓧鏁拌秴鍑轰簡闄愬埗鎵€浠ユ墦绠楀皢鍚庨潰鐨勯儴鍒嗗崟鐙嫀鍑烘潵鍐? 杩欐牱涔熸洿濂界殑鍐欏嚭鐩稿姣旇緝娣卞叆鐨勪竴鐐圭殑鍐呭, 瀵逛簬 鍦ㄧ嚎鍗戝井锛屽鏋滆寰楄繖绡囨枃绔犲浣犳湁甯姪鐨勮瘽娆㈣繋澶у鐐逛釜璧烉煈?/p>
瀵逛簬Event Loop(浜嬩欢杞锛夋墍娑夊強鐨勭煡璇嗘蹇靛お澶氫簡锛屽鏋滀笂鏉ュ氨璁蹭竴澶у爢姒傚康鎬х殑涓滆タ澶灟鐕ヤ笖浠庝竴寮€濮嬪氨鏄寜鐓ф垜鐨勬€濊矾鏉ヨ蛋鐨勶紝鎵€浠ユ垜鎵撶畻鎹竴绉嶆柟寮忔潵鍐欒繖绡囨枃绔狅紝浣犲厛鎸夌収浣犱箣鍓嶅浜嶦vent Loop(浜嬩欢杞)鐨勭悊瑙f潵瑙h繖閬撻锛屾垜鍦ㄥ悗闈㈠啓鍑烘垜浠嶦vent Loop鐨勭悊瑙f€濊€冭繖棰樼殑鏂瑰紡銆備袱绉嶄笉鍚岀殑鐞嗚В銆佹兂娉曘€佷簰鐩哥鎾烇紝鎴戝彲鑳芥湁鐞嗚В涓嶅鐨勶紝浣犱篃鍙兘鏈変箣鍓嶅拷鐣ョ殑涓€浜涚煡璇嗙偣锛屾垜浠?/p>
涓嶅ソ鎰忔€濇斁閿欎簡馃槄锛岃繖寮犲浘銆愬墠绔綋绯汇€?/code>杩欑被鏂囩珷鍐呭涓€瀹氭槸鍖呮嫭浣嗕笉闄愪簬鏍囬鐨勶紝鎴戜細灏藉彲鑳界殑鎷撳睍銆佹繁鍏ャ€佷互鍐欏嚭楂樿川閲忕殑濂芥枃绔犮€?/p>
锛夎繘琛屾彃鍏ユ搷浣滐紝鍜屾爤涓€鏍凤紝闃熷垪鏄竴绉嶆搷浣滃彈闄愬埗鐨勭嚎鎬ц〃銆傝繘琛屾彃鍏ユ搷浣滅殑绔О涓洪槦灏撅紝杩涜鍒犻櫎鎿嶄綔鐨勭绉颁负闃熷ご銆?nbsp;闃熷垪涓病鏈夊厓绱犳椂锛岀О涓?span>绌洪槦鍒?/strong>銆?/p>
浠庝竴閬撻寮曞嚭瀵笶vent Loop鐨勬€濊€?/span>
闃熷垪鐨勬暟鎹厓绱犲張绉颁负闃熷垪鍏冪礌銆傚湪闃熷垪涓彃鍏ヤ竴涓槦鍒楀厓绱犵О涓哄叆闃燂紝浠庨槦鍒椾腑鍒犻櫎涓€涓槦鍒楀厓绱犵О涓哄嚭闃熴€傚洜涓洪槦鍒楀彧鍏佽鍦ㄤ竴绔彃鍏ワ紝鍦ㄥ彟涓€绔垹闄わ紝鎵€浠ュ彧鏈夋渶鏃╄繘鍏ラ槦鍒楃殑鍏冪礌鎵嶈兘鏈€鍏堜粠闃熷垪涓垹闄わ紝鏁呴槦鍒楀張绉颁负鍏堣繘鍏堝嚭锛?code class="mq-110">FIFO: first-in-first-out锛?/p>
涓嬮潰鎴戣В閲婁笅JavaScript璇█涓殑鍫嗐€佹爤銆侀槦鍒椼€?/p>
鍫?/strong> 鍫嗭紝 鍔ㄦ€佸垎閰嶇殑鍐呭瓨锛屽ぇ灏忎笉瀹氫篃涓嶄細鑷姩閲婃斁锛屽瓨鏀?span>寮曠敤绫诲瀷锛屾寚閭d簺鍙兘鐢卞涓€兼瀯鎴愮殑瀵硅薄锛屼繚瀛樺湪鍫嗗唴瀛樹腑锛屽寘鍚紩鐢ㄧ被鍨嬬殑鍙橀噺锛屽疄闄呬笂淇濆瓨鐨勪笉鏄彉閲忔湰韬紝鑰屾槸鎸囧悜璇ュ璞$殑鎸囬拡銆傚彲浠ョ畝鍗曠悊瑙d负瀛樺偍浠g爜鍧椼€?/p>
鍫嗙殑浣滅敤锛氬瓨鍌ㄥ紩鐢ㄧ被鍨嬪€肩殑鏁版嵁 js涓殑鏍堝噯纭潵灏嗗簲璇ュ彨璋冪敤鏍?EC Stack)锛屼細鑷姩鍒嗛厤鍐呭瓨绌洪棿锛屼細鑷姩閲婃斁锛屽瓨鏀?span>鍩烘湰绫诲瀷锛岀畝鍗曠殑鏁版嵁娈碉紝鍗犳嵁鍥哄畾澶у皬鐨勭┖闂淬€?/p>
鏍堢殑浣滅敤锛氬瓨鍌ㄥ熀鏈被鍨嬪€硷紝杩樻湁涓€涓緢瑕佺殑浣滅敤銆?span>鎻愪緵浠g爜鎵ц鐨勭幆澧?/strong> 闃熷垪 js涓殑闃熷垪鍙互鍙仛浠诲姟闃熷垪鎴?span>寮傛闃熷垪锛屼换鍔¢槦鍒楅噷瀛樻斁鍚勭寮傛鎿嶄綔鎵€娉ㄥ唽鐨勫洖璋冿紝閲岄潰鍒嗕负涓ょ浠诲姟绫诲瀷锛屽畯浠诲姟( 濂斤紝涓嬮潰鍙互鍥炲埌姝i涓婃潵浜嗐€?/p>
鎬绘墍鍛ㄧ煡JS鏄竴闂ㄥ崟绾跨▼鐨勯潪闃诲鑴氭湰璇█锛孍vent Loop灏辨槸涓轰簡瑙e喅JS寮傛缂栫▼鐨勪竴绉嶈В鍐虫柟妗堛€?/p>
绗竴涓棶棰橈細JavaScript鐨勮癁鐢熷氨鏄负浜嗗鐞嗘祻瑙堝櫒缃戦〉鐨勪氦浜掞紙DOM鎿嶄綔鐨勫鐞嗐€乁I鍔ㄧ敾绛?, 璁捐鎴愬崟绾跨▼鐨勫師鍥犲氨鏄笉鎯宠娴忚鍣ㄥ彉寰楀お澶嶆潅锛屽洜涓哄绾跨▼闇€瑕佸叡浜祫婧愩€佷笖鏈夊彲鑳戒慨鏀瑰郊姝ょ殑杩愯缁撴灉锛堜袱涓嚎绋嬩慨鏀逛簡鍚屼竴涓狣OM鑺傜偣灏变細浜х敓涓嶅繀瑕佺殑楹荤儲锛夛紝杩欏浜庝竴绉嶇綉椤佃剼鏈瑷€鏉ヨ杩欏氨澶鏉備簡銆?/p>
绗簩涓棶棰橈細JavaScript鏄崟绾跨▼鐨勪絾瀹冩墍杩愯鐨勫涓荤幆澧冣€旀祻瑙堝櫒鏄绾跨▼锛屾祻瑙堝櫒鎻愪緵浜嗗悇绉嶇嚎绋嬩緵Event Loop璋冨害鏉ュ崗璋僇S鍗曠嚎绋嬭繍琛屾椂涓嶄細闃诲銆?/p>
鍏堟€荤粨涓€娉釜浜哄浜嶫S杩愯鏈哄埗鐨勭悊瑙o細 浠g爜鎵ц寮€鍚竴涓叏灞€璋冪敤鏍?涓绘爤)鎻愪緵浠g爜杩愯鐨勭幆澧冿紝鍦ㄦ墽琛岃繃绋嬩腑鍚屾浠诲姟鐨勪唬鐮佺珛鍗虫墽琛岋紝閬囧埌寮傛浠诲姟灏嗗紓姝ョ殑鍥炶皟娉ㄥ唽鍒颁换鍔¢槦鍒椾腑锛岀瓑寰呭悓姝ヤ唬鐮佹墽琛屽畬姣曟煡鐪嬪紓姝ユ槸鍚﹀畬鎴愶紝濡傛灉瀹屾垚灏嗗綋鍓嶅紓姝ヤ换鍔$殑鍥炶皟鎷垮埌涓绘爤涓墽琛?/p>
杩涚▼锛氳繘绋嬫槸 CPU 璧勬簮鍒嗛厤鐨勬渶灏忓崟浣?鏄兘鎷ユ湁璧勬簮鍜岀嫭绔嬭繍琛岀殑鏈€灏忓崟浣? 绾跨▼锛氱嚎绋嬫槸 CPU 璋冨害鐨勬渶灏忓崟浣?绾跨▼鏄缓绔嬪湪杩涚▼鐨勫熀纭€涓婄殑涓€娆$▼搴忚繍琛屽崟浣? 瀵逛簬杩涚▼鍜岀嚎绋嬪苟娌℃湁纭垏缁熶竴鐨勬弿杩帮紝鍙互绠€鍗曠殑鐞嗚В锛?/p>
姣斿涓€涓簲鐢ㄧ▼搴? 濡俀Q銆佹祻瑙堝櫒鍚姩鏃朵細寮€鍚竴涓繘绋嬶紝鑰岃杩涚▼鍙互鏈夊涓嚎绋嬫潵杩涜璧勬簮璋冨害鍜屽垎閰嶏紝杈惧埌杩愯绋嬪簭鐨勪綔鐢ㄣ€?/p>
鏇撮€氫織鐨勮瘽璁诧細鎵撳紑QQ搴旂敤绋嬪簭寮€鍚簡杩涚▼鏉ヨ繍琛岀▼搴?QQ), 鏈夊涓嚎绋嬫潵杩涜璧勬簮璋冨害鍜屽垎閰?澶氫釜绾跨▼鏉ュ垎閰嶆墦寮€QQ鎵€鍗犵敤鐨勮繍瀛?锛岃揪鍒拌繍琛岀▼搴?QQ)鐨勪綔鐢? 鐢ㄦ搷浣滅郴缁熸潵浣滀釜渚嬪瓙锛?/p>
绾跨▼渚濊禆杩涚▼锛屼竴涓繘绋嬪彲浠ユ湁涓€涓垨鑰呭涓嚎绋嬶紝浣嗘槸绾跨▼鍙兘鏄睘浜庝竴涓繘绋嬨€?/p>
js鐨勫崟绾跨▼鎸囩殑鏄痡avaScript寮曟搸鍙湁涓€涓嚎绋?/p>
鍗曠嚎绋嬪氨鎰忓懗鐫€锛屾墍鏈変换鍔¢渶瑕佹帓闃燂紝鍓嶄竴涓换鍔$粨鏉燂紝鎵嶄細鎵ц鍚庝竴涓换鍔°€傚鏋滃墠涓€涓换鍔¤€楁椂寰堥暱锛屽悗涓€涓换鍔″氨涓嶅緱涓嶄竴鐩寸瓑鐫€銆俲s 寮曟搸鎵ц寮傛浠g爜鑰屼笉鐢ㄧ瓑寰咃紝鏄洜鏈変负鏈変换鍔¢槦鍒楀拰浜嬩欢杞銆?/p>
GUI 娓叉煋绾跨▼ JS 寮曟搸绾跨▼ 浜嬩欢瑙﹀彂绾跨▼ 瀹氭椂鍣ㄨЕ鍙戠嚎绋?/p>
HTTP 璇锋眰绾跨▼ 鍛硷紝缁堜簬鍥炲埌姝i浜嗭紒 瀵逛簬浜嬩欢杞涓婇潰鍏跺疄宸茬粡瑙i噴鐨勫緢娓呮浜嗭細 浜嬩欢杞灏辨槸瑙e喅javascript鍗曠嚎绋嬪浜庡紓姝ユ搷浣滅殑涓€浜涚己闄凤紝璁?javaScript鍋氬埌鏃㈡槸鍗曠嚎绋?/strong>锛屽張缁濆涓嶄細闃诲鐨勬牳蹇冩満鍒讹紝鏄敤鏉ュ崗璋冨悇绉嶄簨浠躲€佺敤鎴蜂氦浜掋€佽剼鏈墽琛屻€乁I 娓叉煋銆佺綉缁滆姹傜瓑鐨勪竴绉嶆満鍒躲€?/p>
Processing model[1]瑙勮寖瀹氫箟浜?code class="mq-225">Eveent Loop鐨勫惊鐜繃绋嬶細 涓€涓狤veent Loop鍙瀛樺湪锛屽氨浼氫笉鏂墽琛屼笅杈圭殑姝ラ锛?/p>
Eveent Loopp浼氫笉鏂惊鐜笂闈㈢殑姝ラ锛屾鎷鏉ワ細 鍦ㄤ换鍔″鍒?queue)涓敞鍐岀殑寮傛鍥炶皟鍙堝垎涓轰袱绉嶇被鍨嬶紝瀹忎换鍔″拰寰换鍔°€傛垜浠负浜嗘柟渚跨悊瑙e彲浠ヨ涓哄湪浠诲姟闃熷垪涓湁瀹忎换鍔¢槦鍒楀拰寰换鍔¢槦鍒椼€傚畯浠诲姟闃熷垪鏈夊涓紝寰换鍔″彧鏈変竴涓?/p>
瀹忎换鍔?macro Task) 寰换鍔?micro Task) Promise鐨則hen()銆乧atch()銆乫inally()閲岄潰鐨勫洖璋?/p>
process.nextTick(Node 鐜锛?/p>
... 涓汉鐞嗚В鐨勬墽琛岄『搴忥細 浠g爜浠庡紑濮嬫墽琛岃皟鐢ㄤ竴涓叏灞€鎵ц鏍堬紝script鏍囩浣滀负瀹忎换鍔℃墽琛?/p>
鎵ц杩囩▼涓悓姝ヤ唬鐮佺珛鍗虫墽琛岋紝寮傛浠g爜鏀惧埌浠诲姟闃熷垪涓紝浠诲姟闃熷垪瀛樻斁鏈変袱绉嶇被鍨嬬殑寮傛浠诲姟锛屽畯浠诲姟闃熷垪锛屽井浠诲姟闃熷垪銆?/p>
鍚屾浠g爜鎵ц瀹屾瘯涔熷氨鎰忓懗鐫€绗竴涓畯浠诲姟鎵ц瀹屾瘯(script) 1銆佸厛鏌ョ湅浠诲姟闃熷垪涓殑寰换鍔¢槦鍒楁槸鍚﹀瓨鍦ㄥ畯浠诲姟鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟 1-1銆佹湁鐨勮瘽灏卞皢寰换鍔¢槦鍒椾腑鐨勬墍鏈夊井浠诲姟娓呯┖ 2-2銆佸井浠诲姟鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒椾腑锛屽湪姝ゆ鎵ц涓竴骞舵竻绌?/p>
2銆佸鏋滄病鏈夊啀鐪嬬湅瀹忎换鍔¢槦鍒椾腑鏈夋病鏈夊畯浠诲姟锛屾湁鐨勮瘽鎵ц锛屾病鏈夌殑璇濅簨浠惰疆璇㈢涓€娉㈢粨鏉?/p>
2-1銆佹墽琛岃繃绋嬩腑鎵€浜х敓鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?/p>
2-2銆佸畬鎴愬畯浠诲姟涔嬪悗鎵ц娓呯┖寰换鍔¢槦鍒楃殑浠g爜 鎵€浠ユ槸瀹忎换鍔′紭鍏堬紝鍦ㄥ畯浠诲姟鎵ц瀹屾瘯涔嬪悗鎵嶄細鏉ヤ竴娆℃€ф竻绌轰换鍔¢槦鍒椾腑鐨勬墍鏈夊井浠诲姟銆?/p>
灏嗘渶寮€濮嬬殑閭i亾棰樻惉涓嬫潵 涓婇潰浠g爜瀵逛簬Promise鐨勭敤娉曟垜灏变笉澶氳浜? 鍦ㄥ悗闈㈡垜浼氬啓鍏充簬Promise婧愮爜瑙f瀽鐨勬枃绔犮€?/p>
娉ㄦ剰涓€鐐瑰氨鏄疨romise.then().then()锛屽湪娉ㄥ唽寮傛浠诲姟鐨勬椂鍊欙紝绗簩涓猼hen涓殑鍥炶皟鏄緷璧栫涓€涓猼hen涓洖璋冪殑缁撴灉鐨勶紝濡傛灉鎵ц娌℃湁寮傚父鎵嶄細鍦ㄨ寮傛浠诲姟鎵ц瀹屾瘯涔嬪悗娉ㄥ唽鐘舵€佸搴旂殑鍥炶皟 鍏ㄥ眬涓€涓畯浠诲姟鎵ц, 杈撳嚭鍚屾浠g爜銆傛寕杞藉畯1銆佸井1-1銆佸井1-2銆佸井1-3銆佸井1-4銆?-琛ㄧず灞炰簬绗竴娆¤疆璇?/p>
鍚屾浠g爜鎵ц瀹屾瘯锛屽紑濮嬫墽琛屽紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪涓殑浠g爜銆?/p>
寰换鍔¢槦鍒楋細鍙湁涓€涓槦鍒椾笖浼氬湪褰撳墠杞涓€娆℃竻绌?/strong>let obj = {
name: '鍖楁瓕'锛?br> puslic: '鍓嶇鑷椹跨珯'
}
let func = () => {
console.log('hello world')
}macroTask
)鍜屽井浠诲姟(microTask
)銆?/p>
涓轰粈涔堜細鍑虹幇Event Loop
灏忕粨
杩涚▼鍜岀嚎绋?/span>
JS鐨勫崟绾跨▼
娴忚鍣ㄧ殑澶氱嚎绋?/span>
Event Loop
娴忚鍣ㄤ腑鐨凟veent Loop鎵ц椤哄簭
Eveent Loop
浼氫笉鏂惊鐜殑鍘诲彇
tasks
闃熷垪鐨勪腑鏈€鑰佺殑涓€涓猼ask(鍙互鐞嗚В涓哄畯浠诲姟锛夋帹鍏ユ爤涓墽琛岋紝骞跺湪褰撴寰幆閲屼緷娆℃墽琛屽苟娓呯┖
microtask
闃熷垪閲岀殑浠诲姟銆?
microtask
闃熷垪閲岀殑浠诲姟锛屾湁
鍙兘浼氭覆鏌撴洿鏂般€傦紙娴忚鍣ㄥ緢鑱槑锛屽湪涓€甯т互鍐呯殑澶氭dom鍙樺姩娴忚鍣ㄤ笉浼氱珛鍗冲搷搴旓紝鑰屾槸浼氱Н鏀掑彉鍔ㄤ互鏈€楂?0HZ(澶х害16.7ms姣忓抚)鐨勯鐜囨洿鏂拌鍥撅級
瀹忎换鍔″拰寰换鍔′紭鍏堥棶棰?/span>
瑙i鍒嗘瀽杩囩▼
// => 浠g爜涓€鎵ц灏卞紑濮嬫墽琛屼簡涓€涓畯浠诲姟-瀹?
console.log('script start');
setTimeout(() => { // 瀹?nbsp;1
console.log('鍖楁瓕');
}, 1 * 2000);
Promise.resolve()
.then(function() { // 寰?-1
console.log('promise1');
})
.then(function() { // 寰?-4 => 杩欎釜then涓殑浼氱瓑寰呬笂涓€涓猼hen鎵ц瀹屾垚涔嬪悗寰楀埌鍏剁姸鎬佹墠浼氬悜Queue娉ㄥ唽鐘舵€佸搴旂殑鍥炶皟锛屽亣璁句笂涓€涓猼hen涓富鍔ㄦ姏閿欎笖娌℃湁鎹曡幏锛岄偅灏辨敞鍐岀殑鏄繖涓猼hen涓殑绗簩涓洖璋冧簡銆?/span>
console.log('promise2');
});
async function foo() {
await bar() // => await(promise鐨勮娉曠硸)锛屼細寮傛绛夊緟鑾峰彇鍏惰繑鍥炲€?/span>
// => 鍚庨潰鐨勪唬鐮佸彲浠ョ悊瑙d负鏀惧埌寮傛闃熷垪寰换鍔′腑銆?nbsp;杩欓噷鍙互淇濈暀鐤戦棶鍚庨潰浼氳缁嗚
console.log('async1 end') // 寰?-2
}
foo()
function bar() {
console.log('async2 end')
}
async function errorFunc () {
try {
await Promise.reject('error!!!')
} catch(e) {
// => 浠庤繖鍚庨潰寮€濮嬫墍鏈夌殑浠g爜鍙互鐞嗚В涓烘斁鍒板紓姝ラ槦鍒楀井浠诲姟涓?/span>
console.log(e) // 寰?-3
}
console.log('async1');
return Promise.resolve('async1 success')
}
errorFunc().then(res => console.log(res)) // 寰?-5
console.log('script end');绗竴娆℃墽琛?/span>
run: script start銆?nbsp;async2 end銆乻cript end
绗簩娆℃墽琛?/span>
run:
鎵ц寰?span class="mq-390">1
鎵ц寰?span class="mq-392">1
鎵ц寰?span class="mq-394">1
鎵ц寰?span class="mq-400">1-4: promise2
鎵ц鍒氬垰娉ㄥ唽鐨勫井1-5: async1 success
鍒拌繖绗竴娉㈣疆璇㈢粨鏉?/strong>
绗笁娆℃墽琛?/span>
寮€鍚浜屾尝杞锛氭墽琛屽畯1
run: '鍖楁瓕'
鍒拌繖銆傛暣涓疆璇㈢粨鏉熴€?/p>
鍏跺疄鐩稿闅句互鐞嗚В鐨勪篃灏辨槸寰换鍔★紝瀵逛簬寰换鍔′篃灏辨槸涓婇潰璇寸殑鍙湁涓€涓槦鍒椾細鍦?span>姝ゆ杞涓竴娆℃竻绌?鍖呮嫭姝ゆ鎵ц杩囩▼涓墍浜х敓鐨勫井浠诲姟)銆?/p>
涓句釜鏍楀瓙馃尠
浣犲幓鍫傞鎺掗槦鎵撹彍锛屽師鏈綘璁″垝浠婂ぉ鍙悆涓や釜鑿?寰换鍔¢槦鍒椾腑鍙敞鍐屼簡涓や釜鍥炶皟)锛屽湪鎵撹彍鐨勮繃绋嬩腑浣犵湅鍒颁綘鏈€鍠滄鍚冪殑绾㈢儳鑲?寰换鍔℃墽琛岀殑杩囩▼涓亣鍒扮殑鏂扮殑寰换鍔?锛屼綘鑲畾寰楀啀鍔犱釜鑿?灏嗗井浠诲姟鍔犲叆鍒板井浠诲姟闃熷垪)
鎵撴€繘闃?/span>
閫氳繃涓婇潰鐨勮瑙g幇鍦ㄥ彲浠ュ埛鍑犻亾棰樻潵鐪嬬湅鑷繁鎾戞彙鐨勬€庝箞鏍蜂簡銆?/p>
榛勯噾棰?/span>
console.log('1');
setTimeout(() => {
console.log('2');
Promise.resolve().then(() => {
console.log('3');
})
new Promise((resolve) => {
console.log('4');
resolve();
}).then(() => {
console.log('5')
})
})
Promise.reject().then(() => {
console.log('13');
}, () => {
console.log('12');
})
new Promise((resolve) => {
console.log('7');
resolve();
}).then(() => {
console.log('8')
})
setTimeout(() => {
console.log('9');
Promise.resolve().then(() => {
console.log('10');
})
new Promise((resolve) => {
console.log('11');
resolve();
}).then(() => {
console.log('12')
})
})
鐮栫煶棰?/span>
new Promise((resolve, reject) => {
console.log(1)
resolve()
})
.then(() => {
console.log(2)
new Promise((resolve, reject) => {
console.log(3)
setTimeout(() => {
reject();
}, 3 * 1000);
resolve()
})
.then(() => {
console.log(4)
new Promise((resolve, reject) => {
console.log(5)
resolve();
})
.then(() => {
console.log(7)
})
.then(() => {
console.log(9)
})
})
.then(() => {
console.log(8)
})
})
.then(() => {
console.log(6)
})
鐜嬭€呴
Promise.resolve()
.then(() => {
console.log('promise1');
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('timer2')
resolve()
}, 0)
})
.then(async () => {
await foo();
return new Error('error1')
})
.then((ret) => {
setTimeout(() => {
console.log(ret);
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then(res => {
console.log("then: ", res)
})
.catch(err => {
console.log("catch: ", err)
})
}, 1 * 3000)
}, err => {
console.log(err);
})
.finally((res) => {
console.log(res);
throw new Error('error2')
})
.then((res) => {
console.log(res);
}, err => {
console.log(err);
})
})
.then(() => {
console.log('promise2');
})
function foo() {
setTimeout(() => {
console.log('async1');
}, 2 * 1000);
}
setTimeout(() => {
console.log('timer1')
Promise.resolve()
.then(() => {
console.log('promise3')
})
}, 0)
console.log('start');
鑽h€€鐜嬭€?/span>
涓嬮潰璁╂垜浠潵涓€璧峰仛鏈€鍚庤繖閬撻銆?/p>
async function async1() {
console.log('async1 start');
new Promise((resolve, reject) => {
try {
throw new Error('error1')
} catch(e) {
console.log(e);
}
setTimeout(() => { // 瀹?
resolve('promise4')
}, 3 * 1000);
})
.then((res) => { // 寰?-1
console.log(res);
}, err => {
console.log(err);
})
.finally(res => { // 寰?-2 // TODO娉?
console.log(res);
})
console.log(await async2()); // TODO-娉?
console.log('async1 end'); // 寰?-1 // TODO-娉?
}
function async2() {
console.log('async2');
return new Promise((resolve) => {
setTimeout(() => { // 瀹?
resolve(2)
}, 1 * 3000);
})
}
console.log('script start');
setTimeout(() => { // 瀹?
console.log('setTimeout');
}, 0)
async1();
new Promise((resolve) => {
console.log('promise1');
resolve();
})
.then(() => { // 寰?-2
console.log('promise2');
return new Promise((resolve) => {
resolve()
})
.then(() => { // 寰?-3
console.log('then 1-1')
})
})
.then(() => { // 寰?-4
console.log('promise3');
})
console.log('script end');
瑙勫畾
鐜板湪涓轰簡鏂逛究澶у鐞嗚В锛岃璁颁綇涓€涓嬭瀹氾細
-
鍒嗘瀽浠ユ瘡娆¤疆璇㈠仛涓哄垎鏋愶紝鍚屾浠g爜鍧楁槸鐩存帴杈撳嚭缁撴灉鐨? -
寮傛浠诲姟浠g爜鍧椾腑锛岀孩鑹茶〃绀哄畯浠诲姟锛岀豢鑹茶〃绀哄井浠诲姟 -
寰?-
琛ㄧず绗竴娆¤疆璇腑鐨勫井浠诲姟闃熷垪涓殑鎵€鏈夊井浠诲姟锛?寰?-
琛ㄧず绗簩娆★紝浠ユ绫绘帹
绗竴娆¤疆璇?/span>
script鏍囩(瀹?)鎵ц
杈撳嚭鍚屾浠g爜锛?/p>
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
鎸傝浇寮傛浠诲姟:
-() => { // 瀹?
- console.log('setTimeout');
-}
-() => { // 瀹?
- resolve('promise4')
-}
-() => { // 瀹?
- resolve(2)
-}
+() => { // 寰?-1
+ console.log('promise2');
+ return new Promise((resolve) => {
+ resolve()
+}
鍚屾浠g爜瀹屾瘯鐨勫悓鏃剁涓€涓畯浠诲姟涔熸墽琛屽畬姣曪紝寮€濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-763">1-1: promise2 -> 寰?span class="mq-765">1-2: then 1-1 -> 寰?span class="mq-769">1-3: promise3
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
+() => { // 寰?-2
+ console.log('then 1-1')
+}
+() => { // 寰?-3
+ console.log('promise3');
+}
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
娉?
杩欓噷寰楄涓€涓嬶紝寰堝浜鸿涓篴wait灏嗕唬鐮佸悓姝ュ寲鐨勬剰鎬濓紝鍏跺疄await鏄疨romise鐨勮娉曠硸锛屽唴閮ㄧ殑瀹炵幇涔熸槸渚濋潬Promise, 鍏惰癁鐢熶篃灏辨槸涓轰簡浼樺寲promise鐨則hen閾惧啓娉曪紝鐢ㄥ悓姝ョ殑鏂瑰紡缂栧啓寮傛浠g爜锛岃浠g爜鐪嬭捣鏉ユ洿绠€娲佹槑浜?await鐨勭湡瀹炴剰鎬濇槸 async wait(寮傛绛夊緟鐨勬剰鎬?await琛ㄨ揪寮忕浉褰撲簬璋冪敤鍚庨潰杩斿洖promise鐨則hen鏂规硶锛屽紓姝ワ紙绛夊緟锛夎幏鍙栧叾杩斿洖鍊笺€傚嵆 await<==>promise.then
杩欓噷鐨刟sync2鍑芥暟杩斿洖鐨凱romise涓紑鍚簡涓€涓畯浠诲姟锛宎wait寮傛绛夊緟闇€瑕佺瓑寰呭畯浠诲姟鎵ц鎵嶈兘鑾峰彇鍏惰繑鍥炲€硷紝涔熷氨鏄瀹忎换鍔′笉鎵цawait琛ㄨ揪寮忓氨鍘嬫牴涓嶈兘璋冪敤Promise鐨則hen鏂规硶
娉?
鍓嶉潰璇磋繃await琛ㄨ揪寮忓悗闈㈢殑浠g爜鍙互绠€鍗曠悊瑙d负鏀惧叆鍒板井浠诲姟涓紝浣嗘槸鍓嶉潰await 琛ㄨ揪寮忓帇鏍瑰氨娌℃湁鑾峰彇寮傛绛夊緟鐨勭粨鏋滆繖鍚庨潰鐨勪唬鐮佷粠璺冲嚭褰撳墠鎵ц鏍堝悗灏卞帇鏍规病鏈夋寕杞藉埌寮傛浠诲姟涓紝鏈変簺鏁欑▼璇寸殑await 琛ㄨ揪寮忓悗闈㈢殑浠g爜鍙互鐪嬫垚寰换鍔¢槦鍒楃殑绗竴涓繖绉嶈娉曟槸閿欒鐨勶紒
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
寰?span class="mq-796">1-1: promise2 -> 寰?span class="mq-798">1-2: then 1-1 -> 寰?span class="mq-802">1-3: promise3
绗簩娆¤疆璇?/span>
涓婇潰绗竴娉㈣疆璇㈢粨鏉燂紝寮€鍚浜屾尝杞
鎵ц绗簩涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹?span class="mq-812">2锛歴etTimeout
瀹忎换鍔℃墽琛屽畬姣曟病鏈変骇鐢熸柊鐨勫井浠诲姟锛屼篃娌℃湁浜х敓鏂扮殑瀹忎换鍔°€傜浜屾杞缁撴潫
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
瀹?锛歴etTimeout
绗笁娆¤疆璇?/span>
鎵ц绗笁涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹忎换鍔℃湰韬病鏈夎緭鍑哄暐锛屼笉杩囩‘瀹氫簡涓?span class="mq-825">Promise鐨勭姸鎬佸苟浼犻€掍簡涓?span class="mq-826">'promise4'缁欎笅涓€涓猼hen涓殑鎴愬姛鍥炶皟
瀹忎换鍔℃墽琛岃繃绋嬩腑浜х敓鐨勬柊鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?
+(res) => { // 寰?-1
+ console.log(res);
+}
瀹忎换鍔℃墽琛屽畬姣曞紑濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-838">3-1: promise4 -> 寰?span class="mq-840">3-2: undefined
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
+res => { // 寰?-2 // TODO娉?
+ console.log(res);
+}
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
寰?span class="mq-858">3-1: promise4 -> 寰?span class="mq-860">3-2: undefined
娉?
鍓嶉潰璇磋繃promise.finally()涔熸槸寰换鍔★紝finally鍙互鐞嗚В涓轰笉绠romise鐨勭姸鎬佹槸鎴愬姛鎴栧け璐ラ兘瑕佹墽琛屾垜銆備絾鏄垜涓嶆帴鍙椾换浣曠粨鏋溿€傚洜姝inally鎺ュ彈涓嶅埌杩斿洖鍊紃es涓簎ndefined
绗洓娆¤疆璇?/span>
鎵ц绗洓涓畯浠诲姟闃熷垪(瀹忎换鍔¢槦鍒楀彧瀛樻斁涓€涓畯浠诲姟)锛?/p>
瀹忎换鍔℃湰韬病鏈夎緭鍑哄暐锛屼笉杩囩‘瀹氫簡涓?span class="mq-873">Promise鐨勭姸鎬佸苟浼犻€掍簡涓?span class="mq-874">2缁欎笅涓€涓猼hen涓殑鎴愬姛鍥炶皟
瀹忎换鍔℃墽琛岃繃绋嬩腑浜х敓鐨勬柊鐨勫井浠诲姟鏀惧埌寰换鍔¢槦鍒?
涓婇潰璇磋繃await => Promise.then(), 涓婇潰瀹忎换鍔℃墽琛屽畬姣曠‘瀹氫簡promise鐘舵€佸彲浠ュ幓鑾峰彇寮傛绛夊緟鐨勭粨鏋溿€傜浉褰撲簬杩欐牱锛歅romise.then((res) => {return res}) 鑰宎wait琛ㄨ揪寮忓悗闈㈢殑浠g爜鐩稿綋浜庡湪寮傛绛夊緟鑾峰彇缁撴灉鍚?/strong>鏀惧埌寰换鍔¢槦鍒椾腑 鐩稿綋浜庤繖鏍凤細Promise.then((res) => {return res}).finally(() => {}), 鍙湁鍦╝wait 琛ㄨ揪寮忓墠闈㈣幏鍙栧埌缁撴灉鍚庢墠浼氬湪浠g爜鎸傚湪鍒板紓姝ラ槦鍒椾腑
鍙互鍋氫釜瀹為獙灏嗕笂闈㈠紓姝ョ瓑寰呭畾鏃跺櫒鐨勫€艰瀹氫负鏇撮暱鏃堕棿锛岃繖涓椂鍊檃wait琛ㄨ揪寮忓悗闈㈢殑浠g爜鏄笉涓哄搷搴旂殑锛屽彧鏈夎幏鍙栧埌浜嗗紓姝ョ瓑寰呯殑缁撴灉锛屾墠浼氬搷搴斻€?/p>
+(res) => {return res} // 寰?-1
+() => {async1 end} // 寰?-2
瀹忎换鍔℃墽琛屽畬姣曞紑濮嬫竻绌哄紓姝ヤ换鍔′腑鐨勫井浠诲姟闃熷垪锛?/p>
寰?span class="mq-887">4-1: 2 -> 寰?span class="mq-890">4-2: async1 end
鎵ц寰换鍔′腑鎵€浜х敓鏂扮殑寰换鍔? 鏀惧埌寰换鍔¢槦鍒椾腑锛岃寰换鍔′篃浼氬湪姝ゆ杞涓娓呯┖:
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫井浠诲姟
鎵ц寰换鍔¤繃绋嬩腑鎵€浜х敓鐨勫畯浠诲姟鏀惧埌鏂板畯浠诲姟闃熷垪涓細
鏈寰换鍔℃墽琛屾病鏈変骇鐢熸柊鐨勫畯浠诲姟
姝ゆ杞缁撴潫杈撳嚭缁撴灉鏈夛細
寰?span class="mq-904">4-1: 2 -> 寰?span class="mq-907">4-2: async1 end
鎵€鏈夎疆璇㈠畬姣曚箣鍚庣殑瀹屾暣缁撴灉
script start -> async1 start -> error1 -> async2 -> promise1 -> script end
寰?span class="mq-915">1-1: promise2 -> 寰?span class="mq-917">1-2: then 1-1 -> 寰?span class="mq-921">1-3: promise3
瀹?span class="mq-923">2锛歴etTimeout
寰?span class="mq-924">3-1: promise4 -> 寰?span class="mq-926">3-2: undefined
寰?span class="mq-929">4-1: 2 -> 寰?span class="mq-932">4-2: async1 end
濡傛灉浣犲洓閬撻鍏ㄥ鐨勮瘽锛岄偅涔堟伃鍠滀綘銆?/p>
瀵逛簬銆愬墠绔綋绯汇€戣繖绯诲垪鐨勬枃绔犳垜鏄姳鐫€寰堣鐪燂紝寰堟兂鍐欏ソ鐨勫績鎬佺殑锛屼絾姣曠珶鎴戣繕鏄墠绔皬鐧?amp;鍐欎綔鏂颁汉锛屽鏋滄枃绔犱腑鏈夐偅鍧楀啓鐨勪笉澶ソ鎴栨湁闂娆㈣繋澶у鎸囧嚭锛屾垜涔熶細鍦ㄥ悗闈㈢殑鏂囩珷涓嶅仠淇敼銆備篃甯屾湜鑷繁杩涙鐨勫悓鏃惰兘璺熶綘浠竴璧锋垚闀裤€傚枩娆㈡垜鏂囩珷鐨勬湅鍙嬩滑涔熷彲浠ュ叧娉ㄤ竴涓?/p>
鎴戜細寰堟劅婵€绗竴鎵瑰叧娉ㄦ垜鐨勪汉銆?span>姝ゆ椂锛屽勾杞荤殑鎴戝拰浣狅紝杞昏涓婇樀锛涜€屽悗锛屽瘜瑁曠殑浣犲拰鎴戯紝婊¤浇鑰屽綊銆?/strong> 銆愬墠绔綋绯汇€戜粠鍦板熀寮€濮嬫墦閫犱竴搴т竾涓堥珮妤?/span>[8] 娣卞叆鐞嗚В JavaScript Event Loop[9] Processing model: https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model 姝e湪杩愯鐨則ask: https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task currently running task: https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task microtasks浠诲姟妫€鏌ョ偣: https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint WorkerGlobalScope: https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope Web workers: https://html.spec.whatwg.org/multipage/workers.html#workers run a worker: https://html.spec.whatwg.org/multipage/workers.html#run-a-worker 銆愬墠绔綋绯汇€戜粠鍦板熀寮€濮嬫墦閫犱竴搴т竾涓堥珮妤? https://juejin.im/post/6867784542338416648#comment 娣卞叆鐞嗚В JavaScript Event Loop: https://zhuanlan.zhihu.com/p/34229323绯诲垪鏂囩珷
鍙傝€冩枃绔?/span>
鍙傝€冭祫鏂?/span>
浜ゆ祦璁ㄨ
濡傛灉浣犱笉鎯冲姞缇わ紝鍙槸鎯冲姞鎴戜篃鏄彲浠ョ殑銆?/p>
濡傛灉瑙夊緱杩欑瘒鏂囩珷杩樹笉閿欙紝鏉ヤ釜銆愬垎浜€佺偣璧炪€佸湪鐪嬨€戜笁杩炲惂锛岃鏇村鐨勪汉涔熺湅鍒皛
以上是关于浠庝竴閬撻潰璇曢璋堣皥瀵?EventLoop 鐨勭悊瑙?/h1>