JavaScript 筆記五:同步店雅、異步葫松、Promise

都是本人理解,筆記大致概念底洗,不詳細也并非完全正確,所以僅供參考亥揖。


同步珊擂、異步

JS 代碼的執(zhí)行费变,可以理解為任務(wù)的執(zhí)行,則其中有同步任務(wù)和異步任務(wù)挚歧。

同步任務(wù)是指在主線程上的任務(wù)扛稽,只有前面一個執(zhí)行完畢,才會再執(zhí)行下一個滑负。
同步任務(wù)好理解,異步任務(wù)的執(zhí)行主要是以下步驟:

  1. 主線程任務(wù)進行矮慕,若發(fā)現(xiàn)異步任務(wù),將其移入任務(wù)隊列
  2. 主線程任務(wù)結(jié)束痴鳄,開始執(zhí)行任務(wù)隊列的異步任務(wù)
  3. 任務(wù)隊列任務(wù)進行瘟斜,若發(fā)現(xiàn)異步任務(wù),將其移入任務(wù)隊列后
  4. 重復步驟3直至沒有任務(wù)隊列沒有任務(wù),結(jié)束螺句。

Promise

都知道異步任務(wù)的 callback 的循環(huán)嵌套會讓人抓狂虽惭,所以就有了 Promise,Promise主要解決了JS異步任務(wù)代碼的可讀性問題蛇尚。

Promise 的三種狀態(tài)

  • pending:初始狀態(tài),非成功或失敗
  • fulfilled:操作成功完成
  • rejected:操作失敗

Promise 的狀態(tài)的改變是不可逆的,所以它只會有:

  • pending -> fulfilled
  • pending -> rejected

同步亲雪、異步、Promise 的執(zhí)行順序

有個問題义辕,Promise 是不是異步操作?先看代碼:

setTimeout(() => {
  console.log(1);
}, 0);
new Promise(resolve => {
  console.log(2);
  resolve();
  console.log(3);
}).then(res => {
  console.log(4);
});
console.log(5);

正確結(jié)果是:2灌砖、3、5基显、4、1 撩幽,來一一解析。

先忽略1和5窜醉,如果說 Promise 是同步的,那么應(yīng)該是 2拜英、4、3居凶,但結(jié)果為什么是2、3排监、4杰捂?
猜想是 Promise 將 resolve(); 的方法加了某種延遲舆床,這種延遲不加入任務(wù)隊列,而僅僅是等待 Promise 初始化函數(shù)結(jié)束而開始執(zhí)行谷暮,所以結(jié)果是 2、3湿弦、4。

實際上腾夯,這種操作是存在的,稱之為微任務(wù)蝶俱,微任務(wù)的執(zhí)行順序介于主線程和任務(wù)隊列之間。
PS:任務(wù)隊列的任務(wù)也稱之為宏任務(wù)

所以榨呆,在上述代碼中,1被插入任務(wù)隊列等待积蜻,而 Promise 初始函數(shù)先輸出 2,再因為 resolve(); 為微任務(wù)而先輸出3宙拉,然后因為微任務(wù)的執(zhí)行順序低于主線程,所以輸出 5丙笋,最后微任務(wù)執(zhí)行完畢,執(zhí)行 then 輸出 4不见,最后才執(zhí)行到任務(wù)隊列,輸出 1稳吮,所以最后的結(jié)果是:2、3灶似、5、4酪惭、1。

如果宏任務(wù)包含微任務(wù)春感,那么先后順序是砌创?
答案:執(zhí)行宏任務(wù) > 執(zhí)行包含的微任務(wù) > 執(zhí)行下一個宏任務(wù)。

new Promise(resolve1 => {
  console.log(1);
  setTimeout(() => {
    resolve1();
  }, 0);
  setTimeout(() => {
    console.log(2);
  }, 0);
})
  .then(() => {
    return new Promise(resolve2 => {
      resolve2();
      console.log(3);
    });
  })
  .then(() => {
    console.log(4);
  });
console.log(5);

答案嫩实?1、5甲献、3、4慨灭、2

解析一下:主線程進行,Promise 初始化函數(shù)里輸出 1氧骤,將宏任務(wù) setTimeout - resolve1(); 和setTimeout - 2 放入隊列桶略,輸出 5诲宇,主線程結(jié)束际歼,執(zhí)行宏任務(wù)setTimeout - resolve1(); 姑蓝,執(zhí)行宏任務(wù)下的微任務(wù) resolve1() > then,新的 Promise 的執(zhí)行函數(shù)中旭愧,輸出 3,發(fā)現(xiàn)微任務(wù) resolve2()输枯,執(zhí)行 then 輸出4占贫,此宏任務(wù)結(jié)束桃熄,下一個宏任務(wù) setTimeout - 2 型奥,輸出 2,結(jié)束厢汹。

總結(jié)

Promise并非異步的,僅僅因為resolve和reject方法為微操作界弧,所以會先執(zhí)行初始函數(shù)體,進而再執(zhí)行then夹纫,所以會讓人誤以為是異步的。


ES5 寫 Promise

貼代碼總覺得不夠深層舰讹,寫一下自己的理解,參照 Promise 的三種狀態(tài)钻洒,可以知道有這些屬性锄开。

  • 狀態(tài):記錄 Promise 的狀態(tài)
  • 成功值:成功后的返回值
  • 失敗值:失敗后的返回值
  • 成功回調(diào)方法:成功后的執(zhí)行方法素标,即 then
  • 失敗回調(diào)方法:失敗后的執(zhí)行方法萍悴,即 catch
  • resolve方法:切換狀態(tài)至成功,并執(zhí)行成功回調(diào)方法
  • reject方法:切換狀態(tài)至失敗计维,并執(zhí)行失敗回調(diào)方法
  • then方法:傳入成功回調(diào)方法和失敗函數(shù)方法撕予,將此存儲Promise中鲫惶,切換狀態(tài)時進行對應(yīng)調(diào)用实抡。

過程

  • 當 new 一個 Promise 時,將初始函數(shù)執(zhí)行赏淌,然后將 then 或 catch 的回調(diào)函數(shù)存儲,當切換狀態(tài)成功或切換狀態(tài)失敗函數(shù)時六水,取出存儲的成功回調(diào)或失敗回調(diào)進行執(zhí)行盒延。
  • 像 then 的鏈式調(diào)用缩擂,實質(zhì)是返回一個新的 Promise 即可添寺。
  • then 的支持傳入成功和失敗回調(diào),而 catch 實際上是執(zhí)行 then 且僅傳入失敗回調(diào)博脑。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叉趣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阵谚,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梢什,死亡現(xiàn)場離奇詭異朝聋,居然都是意外死亡,警方通過查閱死者的電腦和手機冀痕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僻他,“玉大人猜极,你說我怎么就攤上這事消玄「” “怎么了翩瓜?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勘高。 經(jīng)常有香客問我坟桅,道長华望,這世上最難降的妖魔是什么仅乓? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮宾抓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘石洗。我一直安慰自己,他們只是感情好讲衫,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挥吵,像睡著了一般花椭。 火紅的嫁衣襯著肌膚如雪忽匈。 梳的紋絲不亂的頭發(fā)上矿辽,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音雕蔽,去河邊找鬼。 笑死批狐,一個胖子當著我的面吹牛前塔,可吹牛的內(nèi)容都是我干的嚣艇。 我是一名探鬼主播华弓,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贰谣!你這毒婦竟也來了迁霎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤考廉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芝此,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體因痛,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡岸更,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年怎炊,在試婚紗的時候發(fā)現(xiàn)自己被綠了谭企。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片评肆。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盹廷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情俄占,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布缸榄,位于F島的核電站祝拯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏佳头。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一砾莱、第九天 我趴在偏房一處隱蔽的房頂上張望瑞筐。 院中可真熱鬧,春花似錦块蚌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辆毡。三九已至,卻和暖如春舶掖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眨攘。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工嚣州, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人该肴。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像匀哄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棉安,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 弄懂js異步 講異步之前铸抑,我們必須掌握一個基礎(chǔ)知識-event-loop。 我們知道JavaScript的一大特點...
    DCbryant閱讀 2,707評論 0 5
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持鹊汛,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠刁憋,并抽取幸運大...
    HetfieldJoe閱讀 11,025評論 26 95
  • 你不知道JS:異步 第三章:Promises 在第二章至耻,我們指出了采用回調(diào)來表達異步和管理并發(fā)時的兩種主要不足:缺...
    purple_force閱讀 2,058評論 0 4
  • 本文作者就是我,簡書的microkof尘颓。如果您覺得本文對您的工作有意義,產(chǎn)生了不可估量的價值疤苹,那么請您不吝打賞我,...
    microkof閱讀 15,947評論 9 40
  • 列表LIST 認識list 列表是有序惫皱、可變的容器類型(元素數(shù)量像樊、值可變),內(nèi)部的元素可以任何類型. 列表是一種序...
    rzlong閱讀 174評論 0 1