3 回答

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

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

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