Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产成人精品免费大全,欧美视频亚洲,国产精品一区二区三

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          詳解JavaScript事件循環(huán)機(jī)制

          詳解JavaScript事件循環(huán)機(jī)制

          所周知,JavaScript 是一門單線程語(yǔ)言,雖然在 html5 中提出了 Web-Worker ,但這并未改變 JavaScript 是單線程這一核心。可看HTML規(guī)范中的這段話:

          To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as described in this section. There are two kinds of event loops: those for browsing contexts, and those for workers.

          為了協(xié)調(diào)事件、用戶交互、腳本、UI 渲染和網(wǎng)絡(luò)處理等行為,用戶引擎必須使用 event loops。Event Loop 包含兩類:一類是基于 Browsing Context ,一種是基于 Worker ,二者是獨(dú)立運(yùn)行的。 下面本文用一個(gè)例子,著重講解下基于 Browsing Context 的事件循環(huán)機(jī)制。

          來(lái)看下面這段 JavaScript 代碼:

           
          setTimeout(function() {
           console.log('setTimeout');
          }, 0);//前端全棧交流學(xué)習(xí)圈:866109386
          //幫助1-3年前端人員,突破技術(shù),提升思維 
          Promise.resolve().then(function() {
           console.log('promise1');
          }).then(function() {
           console.log('promise2');
          });
           
          console.log('script end');
          

          先猜測(cè)一下這段代碼的輸出順序是什么,再去瀏覽器控制臺(tái)輸入一下,看看實(shí)際輸出的順序和你猜測(cè)出的順序是否一致,如果一致,那就說(shuō)明,你對(duì) JavaScript 的事件循環(huán)機(jī)制還是有一定了解的,繼續(xù)往下看可以鞏固下你的知識(shí);而如果實(shí)際輸出的順序和你的猜測(cè)不一致,那么本文下面的部分會(huì)為你答疑解惑。

          任務(wù)隊(duì)列

          所有的任務(wù)可以分為同步任務(wù)和異步任務(wù),同步任務(wù),顧名思義,就是立即執(zhí)行的任務(wù),同步任務(wù)一般會(huì)直接進(jìn)入到主線程中執(zhí)行;而異步任務(wù),就是異步執(zhí)行的任務(wù),比如ajax網(wǎng)絡(luò)請(qǐng)求,setTimeout 定時(shí)函數(shù)等都屬于異步任務(wù),異步任務(wù)會(huì)通過(guò)任務(wù)隊(duì)列( Event Queue )的機(jī)制來(lái)進(jìn)行協(xié)調(diào)。具體的可以用下面的圖來(lái)大致說(shuō)明一下:



          同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行環(huán)境,同步的進(jìn)入主線程,即主執(zhí)行棧,異步的進(jìn)入 Event Queue 。主線程內(nèi)的任務(wù)執(zhí)行完畢為空,會(huì)去 Event Queue 讀取對(duì)應(yīng)的任務(wù),推入主線程執(zhí)行。 上述過(guò)程的不斷重復(fù)就是我們說(shuō)的 Event Loop (事件循環(huán))。

          在事件循環(huán)中,每進(jìn)行一次循環(huán)操作稱為tick,通過(guò)閱讀規(guī)范可知,每一次 tick 的任務(wù)處理模型是比較復(fù)雜的,其關(guān)鍵的步驟可以總結(jié)如下:

          • 在此次 tick 中選擇最先進(jìn)入隊(duì)列的任務(wù)( oldest task ),如果有則執(zhí)行(一次)
          • 檢查是否存在 Microtasks ,如果存在則不停地執(zhí)行,直至清空Microtask Queue
          • 更新 render

          主線程重復(fù)執(zhí)行上述步驟

          可以用一張圖來(lái)說(shuō)明下流程:



          這里相信有人會(huì)想問(wèn),什么是 microtasks ?規(guī)范中規(guī)定,task分為兩大類, 分別是 Macro Task (宏任務(wù))和 Micro Task(微任務(wù)), 并且每個(gè)宏任務(wù)結(jié)束后, 都要清空所有的微任務(wù),這里的 Macro Task也是我們常說(shuō)的 task ,有些文章并沒(méi)有對(duì)其做區(qū)分,后面文章中所提及的task皆看做宏任務(wù)( macro task)。

          (macro)task 主要包含:script( 整體代碼)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 環(huán)境)

          microtask主要包含:Promise、MutaionObserver、process.nextTick(Node.js 環(huán)境)

          setTimeout/Promise 等API便是任務(wù)源,而進(jìn)入任務(wù)隊(duì)列的是由他們指定的具體執(zhí)行任務(wù)。來(lái)自不同任務(wù)源的任務(wù)會(huì)進(jìn)入到不同的任務(wù)隊(duì)列。其中 setTimeout 與 setInterval 是同源的。

          分析示例代碼

          千言萬(wàn)語(yǔ),不如就著例子講來(lái)的清楚。下面我們可以按照規(guī)范,一步步執(zhí)行解析下上面的例子,先貼一下例子代碼(免得你往上翻)。

          console.log('script start');
           
          setTimeout(function() {
           console.log('setTimeout');
          }, 0);//前端全棧交流學(xué)習(xí)圈:866109386
           //幫助1-3年前端人員,提升技術(shù),突破思維
          Promise.resolve().then(function() {
           console.log('promise1');
          }).then(function() {
           console.log('promise2');
          });
           
          console.log('script end');
          

          整體 script 作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到 console.log,輸出 script start

          遇到 setTimeout,其回調(diào)函數(shù)被分發(fā)到宏任務(wù) Event Queue 中

          遇到 Promise,其 then函數(shù)被分到到微任務(wù) Event Queue 中,記為 then1,之后又遇到了 then 函數(shù),將其分到微任務(wù) Event Queue 中,記為 then2

          遇到 console.log,輸出 script end

          至此,Event Queue 中存在三個(gè)任務(wù),如下表:

          • 執(zhí)行微任務(wù),首先執(zhí)行then1,輸出 promise1, 然后執(zhí)行 then2,輸出 promise2,這樣就清空了所有微任務(wù)
          • 執(zhí)行 setTimeout 任務(wù),輸出 setTimeout 至此,輸出的順序是:script start, script end, promise1, promise2, setTimeout
          • so,你猜對(duì)了嗎?

          看看你掌握了沒(méi)

          再來(lái)一個(gè)題目,來(lái)做個(gè)練習(xí):

          console.log('script start');
           
          setTimeout(function() {
           console.log('timeout1');
          }, 10);
           
          new Promise(resolve=> {
           console.log('promise1');
           resolve();
           setTimeout(()=> console.log('timeout2'), 10);
          }).then(function() {
           console.log('then1')
          })
           
          console.log('script end');
          

          這個(gè)題目就稍微有點(diǎn)復(fù)雜了,我們?cè)俜治鱿拢?/p>

          首先,事件循環(huán)從宏任務(wù) (macrotask) 隊(duì)列開(kāi)始,最初始,宏任務(wù)隊(duì)列中,只有一個(gè) scrip t(整體代碼)任務(wù);當(dāng)遇到任務(wù)源 (task source) 時(shí),則會(huì)先分發(fā)任務(wù)到對(duì)應(yīng)的任務(wù)隊(duì)列中去。所以,就和上面例子類似,首先遇到了console.log,輸出 script start; 接著往下走,遇到 setTimeout 任務(wù)源,將其分發(fā)到任務(wù)隊(duì)列中去,記為 timeout1; 接著遇到 promise,new promise 中的代碼立即執(zhí)行,輸出 promise1, 然后執(zhí)行 resolve ,遇到 setTimeout ,將其分發(fā)到任務(wù)隊(duì)列中去,記為 timemout2, 將其 then 分發(fā)到微任務(wù)隊(duì)列中去,記為 then1; 接著遇到 console.log 代碼,直接輸出 script end 接著檢查微任務(wù)隊(duì)列,發(fā)現(xiàn)有個(gè) then1 微任務(wù),執(zhí)行,輸出then1 再檢查微任務(wù)隊(duì)列,發(fā)現(xiàn)已經(jīng)清空,則開(kāi)始檢查宏任務(wù)隊(duì)列,執(zhí)行 timeout1,輸出 timeout1; 接著執(zhí)行 timeout2,輸出 timeout2 至此,所有的都隊(duì)列都已清空,執(zhí)行完畢。其輸出的順序依次是:script start, promise1, script end, then1, timeout1, timeout2

          用流程圖看更清晰:



          總結(jié)

          有個(gè)小 tip:從規(guī)范來(lái)看,microtask 優(yōu)先于 task 執(zhí)行,所以如果有需要優(yōu)先執(zhí)行的邏輯,放入microtask 隊(duì)列會(huì)比 task 更早的被執(zhí)行。

          最后的最后,記住,JavaScript 是一門單線程語(yǔ)言,異步操作都是放到事件循環(huán)隊(duì)列里面,等待主執(zhí)行棧來(lái)執(zhí)行的,并沒(méi)有專門的異步執(zhí)行線程。。

          對(duì)前端的技術(shù),架構(gòu)技術(shù)感興趣的同學(xué)關(guān)注我的頭條號(hào),并在后臺(tái)私信發(fā)送關(guān)鍵字:“前端”即可獲取免費(fèi)的架構(gòu)師學(xué)習(xí)資料

          知識(shí)體系已整理好,歡迎免費(fèi)領(lǐng)取。還有面試視頻分享可以免費(fèi)獲取。關(guān)注我,可以獲得沒(méi)有的架構(gòu)經(jīng)驗(yàn)哦!!


          第一節(jié)課的時(shí)候,我們學(xué)過(guò):


          var a=1; //聲明變量
          if(a%2==0){
          console.log(a);
          }
          a=2;
          if(a%2==0){
          console.log(a);
          }
          a=3;
          if(a%2==0){
          console.log(a);
          }
          a=4;
          if(a%2==0){
          console.log(a);
          }

          。。
          a=10
          if(a%2==0){
          console.log(a);
          }

          這是打印10以內(nèi)的偶數(shù)。

          在這個(gè)例子的下面,還有幾行語(yǔ)句可以達(dá)到相同的效果,但是要精簡(jiǎn)很多。

          for(var i=1;i<=10;i++)
          {
          if(i%2==0)
          {
          console.log(i);
          }
          }

          這個(gè)for語(yǔ)句就是Javascript的循環(huán)語(yǔ)句。

          for語(yǔ)句的語(yǔ)法是這樣的:

          for(初始化語(yǔ)句;條件語(yǔ)句;迭代操作)
          {
          //語(yǔ)句
          }

          在上面的例子中,就是:

          var i=1 這是初始化語(yǔ)句,聲明了一個(gè)i的變量,數(shù)值是1
          i<=10 條件是i小于等于10
          i++ 就是每次執(zhí)行循環(huán),i的值自動(dòng)加1,進(jìn)行迭代操作。


          下面是例子1

          var count;

          for(count=0;count<=10;count=count+1)
          {
          console.log("Count的值是"+count);
          }

          另外,還有幾種循環(huán)語(yǔ)句,這里也一并介紹一下

          1、while語(yǔ)句
          他的語(yǔ)法是:

          while(條件)
          {
          //執(zhí)行語(yǔ)句
          }


          同樣是執(zhí)行打印1到10的值,while是這樣的(例子2):

          var count=0;

          while(count<=10)
          {
          console.log("Count的值是"+count);

          count=count+1; //這個(gè)地方是必須的,否則count一直為0,就會(huì)進(jìn)入死循環(huán)
          }


          2、do..while語(yǔ)句

          它的語(yǔ)法是:

          do {
          //執(zhí)行語(yǔ)句
          }while(條件)


          同樣打印1到10的值(例子3):

          var count=0;

          do {
          console.log("Count的值是"+count);

          count=count+1; //這個(gè)地方是必須的,否則count一直為0,就會(huì)進(jìn)入死循環(huán)
          }while(count<=10);


          最后一個(gè)例子是綜合第三節(jié)的if語(yǔ)句,來(lái)一個(gè)稍微復(fù)雜的應(yīng)用。


          我們來(lái)求一下所有的“水仙花”數(shù)。

          在百度百科里面,水仙花數(shù)的定義是這樣的:

          水仙花數(shù)(Narcissistic number)也被稱為超完全數(shù)字不變數(shù)(pluperfect digital invariant, PPDI)、自戀數(shù)、自冪數(shù)、阿姆斯壯數(shù)或阿姆斯特朗數(shù)(Armstrong number),
          水仙花數(shù)是指一個(gè) 3 位數(shù),它的每個(gè)位上的數(shù)字的 3次冪之和等于它本身(例如:1^3 + 5^3+ 3^3=153)。

          下面是具體的例子(例子4):

          var i;
          var j;
          var k;

          for(var i=1;i<=9;i++){
          for(j=1;j<9;j++){
          for(k=1;k<9;k++){
          var real_number=i*100+j*10+k;
          if(i*i*i+j*j*j+k*K*k==real_number){
          console("發(fā)現(xiàn)水仙花數(shù):"+real_number);
          }
          }
          }

          }

          今天就到這里。

          avaScript入門教程之循環(huán)語(yǔ)句

          循環(huán)語(yǔ)句從字面意思理解就是重復(fù)執(zhí)行,能夠讓計(jì)算機(jī)按照程序員要求重復(fù)執(zhí)行某種操作的能力是所有程序設(shè)計(jì)語(yǔ)言所必須具備的基本能力。在JavaScript程序設(shè)計(jì)語(yǔ)言中同樣具有循環(huán)語(yǔ)句,實(shí)現(xiàn)程序代碼段的重復(fù)執(zhí)行,本文主要從while語(yǔ)句與for語(yǔ)句兩種循環(huán)類型方面對(duì)循環(huán)語(yǔ)句進(jìn)行說(shuō)明。


          JavaScript循環(huán)語(yǔ)句

          JavaScript為前端程序設(shè)計(jì)人員提供了三類基本循環(huán)控制語(yǔ)句,分別為while語(yǔ)句、do-while 語(yǔ)句與for語(yǔ)句。通過(guò)這三種語(yǔ)句程序設(shè)計(jì)人員可以控制程序重復(fù)執(zhí)行某一操作或者操作的組合。JavaScript基本循環(huán)語(yǔ)句執(zhí)行流程描述如下圖所示:

          JavaScript基本循環(huán)流程圖

          通過(guò)上圖我們可知,作為循環(huán)控制語(yǔ)句需要提供循環(huán)執(zhí)行的入口、循環(huán)體與執(zhí)行大的出口三部分。其中出口至關(guān)重要,出口為結(jié)束循環(huán)的條件,如果設(shè)置不好,程序?qū)⒁恢敝貜?fù)執(zhí)行,并進(jìn)入死循環(huán)狀態(tài)。入口我們可以理解為初始條件。出口主要通過(guò)判斷條件控制,在上圖中當(dāng)判斷條件返回值為F時(shí),結(jié)束并退出循環(huán)。以下我們將分別介紹前文提出的三種類型循環(huán)。

          do...while循環(huán)

          在很多程序設(shè)計(jì)語(yǔ)言基礎(chǔ)教程中一般沒(méi)有把do...while放到整個(gè)循環(huán)語(yǔ)句最前面進(jìn)行介紹,主要原因在于與while相比較使用的頻率相對(duì)較低,而且過(guò)多介紹可能讓初學(xué)者對(duì)兩者學(xué)習(xí)記憶產(chǎn)生混淆。此處我們首先介紹do...while 循環(huán),首先我們給出其工作的流程及原理說(shuō)明。

          do...while執(zhí)行流程

          do...while 循環(huán)執(zhí)行過(guò)程描述如上圖所示,當(dāng)開(kāi)始執(zhí)行循環(huán)控制時(shí),首先執(zhí)行一次循環(huán)體,執(zhí)行完成進(jìn)行條件判斷,成立繼續(xù)進(jìn)入循環(huán)體執(zhí)行,否則結(jié)束循環(huán)。因此可知無(wú)論如何都會(huì)執(zhí)行循環(huán)體一次。這也是do..while與while語(yǔ)句最大的區(qū)別。do...while 語(yǔ)法結(jié)構(gòu)與應(yīng)用實(shí)例如下:

          語(yǔ)法說(shuō)明及示例

          基本語(yǔ)法與測(cè)試案例如上所示,執(zhí)行完之后可以得到1-100之間奇數(shù)的和,其和為2500。chrome瀏覽器測(cè)試結(jié)果如下:

          求和計(jì)算結(jié)果

          while循環(huán)語(yǔ)句

          理解了do...while循環(huán)結(jié)構(gòu)之后,再去理解while相對(duì)容易,while語(yǔ)句程序執(zhí)行流程描述如下圖所示:

          while語(yǔ)句執(zhí)行流程

          while語(yǔ)句執(zhí)行流程與循環(huán)控制基本流程完全一致,首先判斷條件,條件成立進(jìn)入循環(huán)體,執(zhí)行完再判斷,直到條件不成立結(jié)束循環(huán)。while循環(huán)語(yǔ)法與示例說(shuō)明如下:

          語(yǔ)法說(shuō)明及示例

          for循環(huán)

          for循環(huán)同樣可以完成循環(huán)流程控制功能,其工作過(guò)程與原理基本與while一致,只是其語(yǔ)法相對(duì)其他兩種較為復(fù)雜一點(diǎn)。需要通過(guò)三個(gè)表達(dá)式控制循環(huán),三個(gè)表達(dá)式分別為初始值、判斷表達(dá)式、增長(zhǎng)值。for循環(huán)基本語(yǔ)法與應(yīng)用示例如下所示:

          語(yǔ)法說(shuō)明及示例

          以上針對(duì)JavaScript程序設(shè)計(jì)語(yǔ)言流程控制中的循環(huán)操作功能進(jìn)行了分析與說(shuō)明,三種控制語(yǔ)句異同也做了解釋,并通過(guò)示例編寫(xiě)了簡(jiǎn)單程序進(jìn)行測(cè)試。


          本頭條號(hào)長(zhǎng)期關(guān)注編程資訊分享;編程課程、素材、代碼分享及編程培訓(xùn)。如果您對(duì)以上方面有興趣或代碼錯(cuò)誤、建議與意見(jiàn),可以聯(lián)系作者,共同探討。更多程序設(shè)計(jì)相關(guān)教程及實(shí)例分享,期待大家關(guān)注與閱讀!JavaScript基礎(chǔ)教程系列教程鏈接如下:

          JavaScript基礎(chǔ)教程(五)流程控制之條件語(yǔ)句

          JavaScript基礎(chǔ)教程(四)二進(jìn)制位運(yùn)算

          JavaScript基礎(chǔ)教程(三)64位浮點(diǎn)數(shù)加法運(yùn)算

          JavaScript基礎(chǔ)教程(二)變量、常量與運(yùn)算符


          主站蜘蛛池模板: 3d动漫精品成人一区二区三| 亚洲AV美女一区二区三区| 婷婷国产成人精品一区二| 亚洲国产精品一区二区九九| 亚洲成AV人片一区二区密柚| 日本精品一区二区三区在线视频 | 日韩精品一区二区三区在线观看| 国产av成人一区二区三区| 精品女同一区二区| 夜夜高潮夜夜爽夜夜爱爱一区| 亚洲蜜芽在线精品一区| 色婷婷一区二区三区四区成人网| 精品国产不卡一区二区三区| 无码精品蜜桃一区二区三区WW| 人妻精品无码一区二区三区| 亚洲日本乱码一区二区在线二产线| 亚洲综合av永久无码精品一区二区 | 国产91久久精品一区二区| 日韩人妻无码一区二区三区综合部| 日本免费电影一区| 日本精品一区二区三区视频| 国产亚洲综合一区二区三区| 国产福利一区二区精品秒拍| 麻豆va一区二区三区久久浪| 韩国精品福利一区二区三区| 韩国一区二区三区| 国产在线精品一区在线观看| 男人免费视频一区二区在线观看| 国产在线无码视频一区| 日韩精品电影一区亚洲| 亚洲国产精品一区二区三区久久| 久久影院亚洲一区| 久久综合精品不卡一区二区| 久久人做人爽一区二区三区| 亚洲AV无码一区二区三区牲色| 日本精品一区二区三本中文| 东京热无码av一区二区| 久久久久99人妻一区二区三区| 中文字幕无码不卡一区二区三区 | 久久久91精品国产一区二区三区| 亚洲线精品一区二区三区|