當前位置:首頁>職場>nodejs如何保證線程安全(用法與面試題分析)
發布時間:2024-01-24閱讀(11)
閱讀本文大約需要 7 分鐘
概述
- 什么是 Promise
- Promise 用法
- Marcro task 與 Micro task
- Promise 面試題
什么是 Promise
Promise 庫是用來處理異步操作的,由于好用且強大,ES6 原生提供了 Promise。
Promise 有三種狀態:
- pending(進行中)
- fulfilled(已成功)
- rejected(已失敗)
如圖,Promise 可以從 pending 轉為 fulfilled ,也可以從 pending 轉為 rejected 。但是一但狀態轉變之后,Promise 就會記住運行結果,再次調用時會直接獲取結果。還有一個要知道的是,當 Promise 在運行的時候,是無法中斷執行的。
但是在實際編程當中,會用 resolved 代指 fulfilled 。
Promise 用法
const myPromise = new Promise(function (resolve, reject) { if (true) {//異步操作成功 resolve("success"); } else { reject("there is some error!"); }})myPromise.then(function (value) { console.log("111"); console.log(value);}, function (error) { console.log("222"); console.log(error)});//運行結果://111//success
Promise 的構造函數接受兩個由 JavaScript 引擎提供的回調函數,分別是:resolve,reject。resolve 是操作成功時的回調函數,與此同時 Promise 的狀態由 pending 轉化為 resolved。reject 是操作失敗的回到函數,與此同時 Promise 的狀態由 pending 轉化為 reject。
Promise 實例生成之后,使用 then 方法繼續操作。then 方法接受兩個回調函數作為參數。分別對應構造 Promise 的時候的兩個回調函數(resolv,reject)
Promise.then() 與 Promise.catch()
Promise.catch() 相當于 Promise.then(null, rejection),用于捕獲錯誤的回調函數。
const myPromiseCatch = new Promise(function (resolve, reject) { if (true) { reject(new Error("there are some errors!!!")) } else { resolve("asdf"); }});myPromiseCatch.then(function (value) { console.log(value)}).catch(function (error) { console.log(error)})//運行結果:there are some errors!!!
Promise.all
將多個 promise 實例合并成一個。
const p = Promise.all([p1, p2, p3]);
p的狀態由p1、p2、p3決定:
(1)只有p1、p2、p3的狀態都變成fulfilled,p的狀態才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回調函數。
(2)只要p1、p2、p3之中有一個被rejected,p的狀態就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。
// 生成一個Promise對象的數組const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getjson(/post/ id ".json");});Promise.all(promises).then(function (posts) { // ...}).catch(function(reason){ // ...});
Marcro task 與 Micro task
為什么要寫這個呢?是為了接下來的面試題而做鋪墊。
關于這個,我搜索了挺多文章,好像都沒有解釋得通的。還好,最后搜到了一篇比較滿意的(見文末)。
nodejs 中的 EventLoop 有任務隊列 EventQueue(TaskQueue)
Task 分為兩大類:Marcro task 與 Micro task;兩者的執行順序:每執行完成一個 Macro Task 就要清空當前所有的 Micro Task。接下來是一些分類:
Macrotask
- setImmediate
- setTimeout
- setInterval
Microtask
- process.nextTick
- Promise
- Object.observe
- MutaionObserver
(圖作者@BusyRich)。
再進一步劃分,從微觀實現的角度講, 引擎都會有三個 Task Queue:
- Macro Task Queue -----> 處理 Micro Task Queue
- Micro Task Queue ------> 處理 Promise 等 microtask
- Tick Task Queue -------> 處理 process.nextTick
那么在一個事件循環中,其偽代碼展示如下:
for (macroTask of macroTaskQueue) { // 1. Handle current MACRO-TASK handleMacroTask(); // 2. Handle all NEXT-TICK for (nextTick of nextTickQueue) { handleNextTick(nextTick); } // 3. Handle all MICRO-TASK for (microTask of microTaskQueue) { handleMicroTask(microTask); } }
Promise 面試題
這個題是大佬 nswbmw 的,我覺得還是挺不錯的,有些題我們能夠直接看注釋看懂。而有些題則需要涉及到上面的 Marcro task 與 Micro task 的知識。
Macrotask 與 Microtask 核心概念(點擊閱讀原文跳轉鏈接)
ECMAScript 6 入門(點擊閱讀原文跳轉鏈接)
歡迎分享轉載→http://www.avcorse.com/read-215947.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖