日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript等待异步线程完成_JavaScript 中的异步原理

發(fā)布時間:2025/4/16 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript等待异步线程完成_JavaScript 中的异步原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

來源:極鏈科技
作者:周哲


所謂“異步” ,簡單說就是一個任務(wù)分成兩段,先執(zhí)行第一段,然后轉(zhuǎn)而執(zhí)行其他任務(wù),等做好了準(zhǔn)備,再回過頭執(zhí)行第二段。比如,有一個任務(wù)是讀取文件進(jìn)行處理,異步的執(zhí)行過程就是下面這樣。
常見的瀏覽器無響應(yīng)(假死),往往就是因?yàn)槟骋欢?Javascript 代碼長時間運(yùn)行(比如死循環(huán)),導(dǎo)致整個頁面卡在這個地方,其他任務(wù)無法執(zhí)行。
為了解決這個問題,Javascript 語言將任務(wù)的執(zhí)行模式分成兩種:同步( Synchronous )和異步( Asynchronous )。

異步編程原理
JavaScript 引擎負(fù)責(zé)解析,執(zhí)行 JavaScript 代碼,但它并不能單獨(dú)運(yùn)行,通常都得有一個宿主環(huán)境,一般如瀏覽器或 Node 服務(wù)器,前文說到的單線程是指在這些宿主環(huán)境創(chuàng)建單一線程,提供一種機(jī)制,調(diào)用 JavaScript 引擎完成多個 JavaScript 代碼塊的調(diào)度,這種機(jī)制就稱為事件循環(huán)( Event Loop )。關(guān)于事件循環(huán)流程分解如下:

  • 宿主環(huán)境為JavaScript 創(chuàng)建線程時,會創(chuàng)建堆 (heap) 和棧 (stack) ,堆內(nèi)存儲 JavaScript 對象,棧內(nèi)存儲執(zhí)行上下文;
  • 棧內(nèi)執(zhí)行上下文的同步任務(wù)按序執(zhí)行,執(zhí)行完即退棧,而當(dāng)異步任務(wù)執(zhí)行時,該異步任務(wù)進(jìn)入等待狀態(tài)(不入棧),同時通知線程:當(dāng)觸發(fā)該事件時(或該異步操作響應(yīng)返回時),需向消息隊(duì)列插入一個事件消息;
  • 當(dāng)事件觸發(fā)或響應(yīng)返回時,線程向消息隊(duì)列插入該事件消息(包含事件及回調(diào));
  • 當(dāng)棧內(nèi)同步任務(wù)執(zhí)行完畢后,線程從消息隊(duì)列取出一個事件消息,其對應(yīng)異步任務(wù)(函數(shù))入棧,執(zhí)行回調(diào)函數(shù),如果未綁定回調(diào),這個消息會被丟棄,執(zhí)行完任務(wù)后退棧;
  • 當(dāng)線程空閑(即執(zhí)行棧清空)時繼續(xù)拉取消息隊(duì)列下一輪消息(next tick ,事件循環(huán)流轉(zhuǎn)一次稱為一次 tick )。

  • 很多的隊(duì)列先后按順序執(zhí)行任務(wù)就形成了 Event異步編程實(shí)現(xiàn)1 :回調(diào)函數(shù)
    優(yōu)點(diǎn):簡單、容易理解和部署。
    缺點(diǎn):不利于代碼的閱讀和維護(hù),各個部分之間高度耦合( Coupling ),流程會很混亂。2 : Promise 對象
    一個 promise 可能有三種狀態(tài):等待( pending )、已完成( fulfilled )、已拒絕( rejected ) ;

    resolve ,接受一個成功值,傳遞給綁定的 fulfilled 回調(diào)函數(shù)中。主要工作是將當(dāng)前狀態(tài)變?yōu)?fulfilled 狀態(tài),同時調(diào)用綁定的 fulfilled 回調(diào)函數(shù)。reject ,接受一個失敗信息,傳遞給綁定的 rejected 回調(diào)函數(shù)中。主要工作是將當(dāng)前狀態(tài)變?yōu)?rejected 狀態(tài),同時調(diào)用綁定的 rejected 回調(diào)函數(shù)。then 方法返回一個 Promise 。它有兩個參數(shù),分別為 Promise 在成功和失敗情況下的回調(diào)函數(shù)。
    語法:


    概括來說 promise 是對異步的執(zhí)行結(jié)果的描述對象。3 : Generator
    Generator 函數(shù)是 ES6 提供的一種異步編程解決方案 ,允許函數(shù)的暫停和恢復(fù)。
    異步任務(wù)的封裝:


    整個過程類似于,瀏覽器遇到標(biāo)識符 * 之后,就明白這個函數(shù)是生成器函數(shù),一旦遇到 yield 標(biāo)識符,就會將以后的函數(shù)放入此異步函數(shù)之內(nèi),待異步返回結(jié)果后再進(jìn)行執(zhí)行。更深一步,從內(nèi)存上來講:
    普通函數(shù)在被調(diào)用時,JS 引擎會創(chuàng)建一個棧幀,在里面準(zhǔn)備好局部變量、函數(shù)參數(shù)、臨時值、代碼執(zhí)行的位置(也就是說這個函數(shù)的第一行對應(yīng)到代碼區(qū)里的第幾行機(jī)器碼),在當(dāng)前棧幀里設(shè)置好返回位置,然后將新幀壓入棧頂。待函數(shù)執(zhí)行結(jié)束后,這個棧幀將被彈出棧然后銷毀,返回值會被傳給上一個棧幀。
    當(dāng)執(zhí)行到 yield 語句時, Generator 的棧幀同樣會被彈出棧外,但 Generator 在這里耍了個花招 —— 它在堆里保存了棧幀的引用(或拷貝)!這樣當(dāng) it.next 方法被調(diào)用時, JS 引擎便不會重新創(chuàng)建一個棧幀,而是把堆里的棧幀直接入棧。因?yàn)闂锉4媪撕瘮?shù)執(zhí)行所需的全部上下文以及當(dāng)前執(zhí)行的位置,所以當(dāng)這一切都被恢復(fù)如初之時,就好像程序從原本暫停的地方繼續(xù)向前執(zhí)行了。
    而因?yàn)槊看?yield 和 it.next 都對應(yīng)一次出棧和入棧,所以可以直接利用已有的棧機(jī)制,實(shí)現(xiàn)值的傳出和傳入。

    總結(jié)

    以上是生活随笔為你收集整理的javascript等待异步线程完成_JavaScript 中的异步原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。