3 回答

TA貢獻1798條經驗 獲得超7個贊
是在用
async
粗人await
的線嗎?
一點都不。它只是使用 promises 的語法糖(真的非常有用的糖),而這又只是一種(真的非常有用的)使用回調的形式化方式。它很有用,因為您可以異步等待(不阻塞 JavaScript 主線程)本質上是異步的事物(如 HTTP 請求)。
如果您需要使用線程,請使用web workers、Node.js worker threads或您的環境提供的任何多線程。根據規范(現在),一次只允許一個線程在給定的 JavaScript“領域”(非常松散:您的代碼運行的全局環境及其關聯的對象等)中工作,因此只有一個線程一次可以訪問該領域內的變量等,但線程可以通過消息傳遞(包括在它們之間傳輸對象而不制作副本)和共享內存進行協作。
例如:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
isThisLikeTwoThreads
以下是調用時代碼的作用:
slowFunction
被同步調用并將其返回值分配給a
.fastFunction
被同步調用并將其返回值分配給b
.當
isThisLikeTwoThreads
到達時await a
,它包裝a
在一個承諾中(就像你做的那樣Promise.resolve(a)
)并返回一個新的承諾(不是同一個)。讓我們調用圍繞a
“aPromise
”的承諾和函數“functionPromise
”返回的承諾。稍后
aPromise
結算時,如果被拒絕functionPromise
,則以相同的拒絕原因拒絕,并跳過以下步驟;如果滿足,則下一步完成中的代碼
isThisLikeTwoThreads
繼續包裝b
在 promise (bPromise
) 中并等待其解決結算時
bPromise
,如果被拒絕functionPromise
則以同樣的拒絕原因被拒絕;如果已實現,則中的代碼isThisLikeTwoThreads
會繼續記錄實現值aPromise
,bPromise
然后functionPromise
用該值實現undefined
上面的所有工作都是在完成調用的 JavaScript 線程上isThisLikeTwoThreads
完成的,但它分布在多個“作業”(JavaScript 術語;HTML 規范稱它們為“任務”,并詳細說明了它們如何進行'在瀏覽器上處理)。如果slowFunction
或fastFunction
啟動了一個異步進程并為此返回了一個承諾,那么當 JavaScript 線程正在做其他事情時,該異步進程(例如,瀏覽器執行的 HTTP 調用)可能會繼續與 JavaScript 線程并行,或者(如果它也在主線程上的 JavaScript 代碼)可能已經競爭 JavaScript 線程上的其他工作(通過將作業添加到作業隊列和線程在循環中處理它們來競爭)。
但是使用 promises 不會添加線程。:-)

TA貢獻1811條經驗 獲得超6個贊
我建議您閱讀本文以了解答案是否定的:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
總而言之,運行時使用多個線程進行內部操作(網絡、磁盤...用于 Node.js 環境、渲染、indexedDB、網絡...用于瀏覽器環境)但是您編寫的 JavaScript 代碼和您從中導入的代碼不同的庫將始終在單個線程中執行。異步操作會觸發回調,回調會一個一個排隊執行。
基本上執行此功能時會發生什么:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
執行slowFunction。執行fastFunction。當promise 和promise 已解決時,將其余代碼 ( console.log(await a, await b))入隊。在返回后以及可能的排隊回調返回后,在同一線程中運行。假設和都返回承諾,這相當于:abconsole.log isThisLikeTwoThreadsslowFunctionfastFunction
function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
a.then(aResult => b.then(bResult => console.log(aResult, bResult)));
}

TA貢獻2039條經驗 獲得超8個贊
相似但不相同。Javascript 一次只會做“一件事”。它基本上是單線程的。也就是說,它可能看起來很奇怪,因為結果可能似乎以不同的順序到達 - 異步和等待等功能加劇了這種情況。
例如,即使您以 70fps 的速度渲染后臺進程,在可用于完成承諾或接收事件通知的渲染邏輯中也存在小間隙——正是在這些時刻,承諾完成,給人以多線程的錯覺。
如果你真的想鎖定瀏覽器,試試這個:
let a = 1;
while (a == 1){
console.log("doing a thing");
}
你永遠不會讓 javascript 再次工作,而 chrome 或任何會扼殺你的腳本的東西。原因是當它進入該循環時——沒有任何東西會再次接觸它,不會呈現任何事件,也不會傳遞任何承諾——因此,單線程。
如果這是一個真正的多線程環境,您可以通過將變量更改為新值來從外部打破該循環。
添加回答
舉報