在浏览器中,JavaScript引擎是单线程执行的。也就是说,在同一时间内,只能有一段代码被JavaScript引擎执行。页面加载时,JavaScript引擎会顺序执行页面上所有JavaScript代码,优先执行同步代码。而异步代码由事件触发引擎按照“事件发生”的顺序添加到JavaScript引擎的任务队列中,待所有同步代码执行结束后,JavaScript引擎会按照任务队列中的顺序来执行异步代码。
也就是说当有多个任务执行时,会按照顺序优先执行同步任务队列,再执行异步任务队列。
setTimeout(function(){ console.log('hello world'); },0);//虽然此处异步任务时间间隔为0,但仍然排在同步队列之后执行 var t = 300000000; for(var i=0;i<=t;i++){//此处进行一次耗时操作 if(i==t){ console.log(t); } }
//结果为
//300000000
//hello world
因此可以利用这一原理,实现简单的链式操作和流程控制:
LazyMan('Hank').sleepFirst(1).eat('breadfast').sleep(2).eat('lunch').sleep(3).eat('dinner');//结果可以不按照顺序执行
function LazyMan(name) { var queue = []; var task = {//待执行的方法 wait: function (second) { return function () { setTimeout(function () { console.log('Wake up after ' + second); next(); }, second * 1000); }; }, eat: function (part) { return function () { console.log('Eat ' + part + '~'); next(); }; }, hi: function () { console.log('Hi! This is ' + name + '!'); next(); } }; queue.push(task.hi); //这个定时器会在链式操作全部推入queue数组中后(即同步代码执行完毕)才会调用 setTimeout(function () { next(); }, 0);
//每次执行next都会把当前queue队列[fn,.....]的第一个方法shift出来并执行,如果队列为空则链式操作执行完毕。
function next() { var fn = queue.shift(); fn && fn(); }
return {
//链式调用的时候会先把这些调用的一系列任务方法push或unshift到一个quue数组中 sleep: function (second) { queue.push(task.wait(second)); return this; }, sleepFirst: function (second) { queue.unshift(task.wait(second)); return this; }, eat: function (part) { queue.push(task.eat(part)); return this; } }; };
//输出
Wake up after 1
Hi! This is Hank!
Eat breadfast~
Wake up after 2
Eat lunch~
Wake up after 3
Eat dinner~
/** * .,:,,, .::,,,::. * .::::,,;;, .,;;:,,....:i: * :i,.::::,;i:. ....,,:::::::::,.... .;i:,. ......;i. * :;..:::;::::i;,,:::;:,,,,,,,,,,..,.,,:::iri:. .,:irsr:,.;i. * ;;..,::::;;;;ri,,,. ..,,:;s1s1ssrr;,.;r, * :;. ,::;ii;:, . ................... .;iirri;;;,,;i, * ,i. .;ri:. ... ............................ .,,:;:,,,;i: * :s,.;r:... ....................................... .::;::s; * ,1r::. .............,,,.,,:,,........................,;iir; * ,s;........... ..::.,;:,,. ...............,;1s * :i,..,. .,:,,::,. .......... .......;1, * ir,....:rrssr;:, ,,.,::. .r5S9989398G95hr;. ....,.:s, * ;r,..,s9855513XHAG3i .,,,,,,,. ,S931,.,,.;s;s&BHHA8s.,..,..:r: * :r;..rGGh, :SAG;;G@BS:.,,,,,,,,,.r83: hHH1sXMBHHHM3..,,,,.ir. * ,si,.1GS, sBMAAX&MBMB5,,,,,,:,,.:&8 3@HXHBMBHBBH#X,.,,,,,,rr * ;1:,,SH: .A@&&B#&8H#BS,,,,,,,,,.,5XS, 3@MHABM&59M#As..,,,,:,is, * .rr,,,;9&1 hBHHBB&8AMGr,,,,,,,,,,,:h&&9s; r9&BMHBHMB9: . .,,,,;ri. * :1:....:5&XSi;r8BMBHHA9r:,......,,,,:ii19GG88899XHHH&GSr. ...,:rs. * ;s. .:sS8G8GG889hi. ....,,:;:,.:irssrriii:,. ...,,i1, * ;1, ..,....,,isssi;, .,,. ....,.i1, * ;h: i9HHBMBBHAX9: . ...,,,rs, * ,1i.. :A#MBBBBMHB##s ....,,,;si. * .r1,.. ,..;3BMBBBHBB#Bh. .. ....,,,,,i1; * :h;.. .,..;,1XBMMMMBXs,.,, .. :: ,. ....,,,,,,ss. * ih: .. .;;;, ;;:s58A3i,.. ,. ,.:,,. ...,,,,,:,s1, * .s1,.... .,;sh, ,iSAXs;. ,. ,,.i85 ...,,,,,,:i1; * .rh: ... rXG9XBBM#M#MHAX3hss13&&HHXr .....,,,,,,,ih; * .s5: ..... i598X&&A&AAAAAA&XG851r: ........,,,,:,,sh; * . ihr, ... . .. ........,,,,,;11:. * ,s1i. ... ..,,,..,,,.,,.,,.,.. ........,,.,,.;s5i. * .:s1r,...................... ..............;shs, * . .:shr:. .... ..............,ishs. * .,issr;,... ...........................,is1s;. * .,is1si;:,....................,:;ir1sr;, * ..:isssssrrii;::::::;;iirsssssr;:.. * .,::iiirsssssssssrri;;:.
参考 http://hushicai.com/2015/05/07/a-frontend-interview-question-of-weixin.html