成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JS引擎:它們是如何工作的?從調(diào)用堆棧到Promise,需要知道的所有內(nèi)容

lavnFan / 438人閱讀

摘要:最受歡迎的引擎是,由和使用,用于,以及使用的。引擎它們是如何工作的全局執(zhí)行上下文和調(diào)用堆棧剛剛了解了引擎如何讀取變量和函數(shù)聲明,它們最終被放入了全局內(nèi)存堆中。事件循環(huán)只有一個(gè)任務(wù)它檢查調(diào)用堆棧是否為空。

為了保證可讀性,本文采用意譯而非直譯。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你!

有沒(méi)有想過(guò)瀏覽器如何讀取和運(yùn)行JS代碼? 這看起來(lái)很神奇,我們可以通過(guò)瀏覽器提供的控制臺(tái)來(lái)了解背后的一些原理。

在Chrome中打開(kāi)瀏覽器控制臺(tái),然后查看Sources這欄,在右側(cè)可以到一個(gè) Call Stack 盒子。

JS 引擎是一個(gè)可以編譯和解釋我們的JS代碼強(qiáng)大的組件。 最受歡迎的JS 引擎是V8,由 Google Chrome 和 Node.j s使用,SpiderMonkey 用于Firefox,以及Safari/WebKit使用的 JavaScriptCore。

雖然現(xiàn)在 JS 引擎不是幫我們處理全面的工作。但是每個(gè)引擎中都有一些較小的組件為我們做繁瑣的的工作。

其中一個(gè)組件是調(diào)用堆棧(Call Stack),與全局內(nèi)存和執(zhí)行上下文一起運(yùn)行我們的代碼。

Js 引擎和全局內(nèi)存(Global Memory)

JavaScript 是編譯語(yǔ)言同時(shí)也是解釋語(yǔ)言。信不信由你,JS 引擎在執(zhí)行代碼之前只需要幾微秒就能編譯代碼。

這聽(tīng)起來(lái)很神奇,對(duì)吧?這種神奇的功能稱(chēng)為JIT(及時(shí)編譯)。這個(gè)是一個(gè)很大的話(huà)題,一本書(shū)都不足以描述JIT是如何工作的。但現(xiàn)在,我們午飯可以跳過(guò)編譯背后的理論,將重點(diǎn)放在執(zhí)行階段,盡管如此,這仍然很有趣。

考慮以下代碼:

var num = 2;
function pow(num) {
    return num * num;
}

如果問(wèn)你如何在瀏覽器中處理上述代碼? 你會(huì)說(shuō)些什么? 你可能會(huì)說(shuō)“瀏覽器讀取代碼”或“瀏覽器執(zhí)行代碼”。

現(xiàn)實(shí)比這更微妙。首先,讀取這段代碼的不是瀏覽器,是JS引擎。JS引擎讀取代碼,一旦遇到第一行,就會(huì)將幾個(gè)引用放入全局內(nèi)存。

全局內(nèi)存(也稱(chēng)為堆)JS引擎保存變量和函數(shù)聲明的地方。因此,回到上面示例,當(dāng) JS引擎讀取上面的代碼時(shí),全局內(nèi)存中放入了兩個(gè)綁定。

即使示例只有變量和函數(shù),也要考慮你的JS代碼在更大的環(huán)境中運(yùn)行:在瀏覽器中或在Node.js中。 在這些環(huán)境中,有許多預(yù)定義的函數(shù)和變量,稱(chēng)為全局變量。 全球記憶將比num和pow更多。

上例中,沒(méi)有執(zhí)行任何操作,但是如果我們像這樣運(yùn)行函數(shù)會(huì)怎么樣呢:

var num = 2;
function pow(num) {
    return num * num;
}
pow(num);

現(xiàn)在事情變得有趣了。當(dāng)函數(shù)被調(diào)用時(shí),JavaScript引擎會(huì)為全局執(zhí)行上下文調(diào)用棧騰出空間。

JS引擎:它們是如何工作的? 全局執(zhí)行上下文和調(diào)用堆棧

剛剛了解了 JS引擎如何讀取變量和函數(shù)聲明,它們最終被放入了全局內(nèi)存(堆)中。

但現(xiàn)在我們執(zhí)行了一個(gè)JS函數(shù),JS引擎必須處理它。怎么做?每個(gè)JS引擎中都有一個(gè)基本組件,叫調(diào)用堆棧。

調(diào)用堆棧是一個(gè)堆棧數(shù)據(jù)結(jié)構(gòu):這意味著元素可以從頂部進(jìn)入,但如果它們上面有一些元素,它們就不能離開(kāi),JS 函數(shù)就是這樣的。

一旦執(zhí)行,如果其他函數(shù)仍然被阻塞,它們就不能離開(kāi)調(diào)用堆棧。請(qǐng)注意,這個(gè)有助于你理解“JavaScript是單線(xiàn)程的”這句話(huà)。

回到我們的例子,當(dāng)函數(shù)被調(diào)用時(shí),JS引擎將該函數(shù)推入調(diào)用堆棧

同時(shí),JS 引擎還分配了一個(gè)全局執(zhí)行上下文,這是運(yùn)行JS代碼的全局環(huán)境,如下所示

想象全局執(zhí)行上下文是一個(gè)海洋,其中全局函數(shù)像魚(yú)一樣游動(dòng),多美好! 但現(xiàn)實(shí)遠(yuǎn)非那么簡(jiǎn)單, 如果我函數(shù)有一些嵌套變量或一個(gè)或多個(gè)內(nèi)部函數(shù)怎么辦?

即使是像下面這樣的簡(jiǎn)單變化,JS引擎也會(huì)創(chuàng)建一個(gè)本地執(zhí)行上下文:

var num = 2;
function pow(num) {
    var fixed = 89;
    return num * num;
}
pow(num);

注意,我在pow函數(shù)中添加了一個(gè)名為fixed的變量。在這種情況下,pow函數(shù)中會(huì)創(chuàng)建一個(gè)本地執(zhí)行上下文,fixed 變量被放入pow函數(shù)中的本地執(zhí)行上下文中。

對(duì)于嵌套函數(shù)的每個(gè)嵌套函數(shù),引擎都會(huì)創(chuàng)建更多的本地執(zhí)行上下文。

JavaScript 是單線(xiàn)程和其他有趣的故事

JavaScript是單線(xiàn)程的,因?yàn)橹挥幸粋€(gè)調(diào)用堆棧處理我們的函數(shù)。也就是說(shuō),如果有其他函數(shù)等待執(zhí)行,函數(shù)就不能離開(kāi)調(diào)用堆棧。

在處理同步代碼時(shí),這不是問(wèn)題。例如,兩個(gè)數(shù)字之間的和是同步的,以微秒為單位。但如果涉及異步的時(shí)候,怎么辦呢?

幸運(yùn)的是,默認(rèn)情況下JS引擎是異步的。即使它一次執(zhí)行一個(gè)函數(shù),也有一種方法可以讓外部(如:瀏覽器)執(zhí)行速度較慢的函數(shù),稍后探討這個(gè)主題。

當(dāng)瀏覽器加載某些JS代碼時(shí),JS引擎會(huì)逐行讀取并執(zhí)行以下步驟:

將變量和函數(shù)的聲明放入全局內(nèi)存(堆)中

將函數(shù)的調(diào)用放入調(diào)用堆棧

創(chuàng)建全局執(zhí)行上下文,在其中執(zhí)行全局函數(shù)

創(chuàng)建多個(gè)本地執(zhí)行上下文(如果有內(nèi)部變量或嵌套函數(shù))

到目前為止,對(duì)JS引擎的同步機(jī)制有了基本的了解。 在接下來(lái)的部分中,講講 JS 異步工作原理。

異步JS,回調(diào)隊(duì)列和事件循環(huán)

全局內(nèi)存(堆),執(zhí)行上下文和調(diào)用堆棧解釋了同步 JS 代碼在瀏覽器中的運(yùn)行方式。 然而,我們遺漏了一些東西,當(dāng)有一些異步函數(shù)運(yùn)行時(shí)會(huì)發(fā)生什么?

請(qǐng)記住,調(diào)用堆棧一次可以執(zhí)行一個(gè)函數(shù),甚至一個(gè)阻塞函數(shù)也可以直接凍結(jié)瀏覽器。 幸運(yùn)的是JavaScript引擎是聰明的,并且在瀏覽器的幫助下可以解決問(wèn)題。

當(dāng)我們運(yùn)行一個(gè)異步函數(shù)時(shí),瀏覽器接受該函數(shù)并運(yùn)行它??紤]如下代碼:

setTimeout(callback, 10000);
function callback(){
    console.log("hello timer!");
}

setTimeout 大家都知道得用得很多次了,但你可能不知道它不是內(nèi)置的JS函數(shù)。 也就是說(shuō),當(dāng)JS 出現(xiàn),語(yǔ)言中沒(méi)有內(nèi)置的setTimeout。

setTimeout瀏覽器API( Browser API)的一部分,它是瀏覽器免費(fèi)提供給我們的一組方便的工具。這在實(shí)戰(zhàn)中意味著什么?由于setTimeout是一個(gè)瀏覽器的一個(gè)Api,函數(shù)由瀏覽器直接運(yùn)行(它會(huì)在調(diào)用堆棧中出現(xiàn)一會(huì)兒,但會(huì)立即刪除)。

10秒后,瀏覽器接受我們傳入的回調(diào)函數(shù)并將其移動(dòng)到回調(diào)隊(duì)列(Callback Queu)中。??紤]以下代碼

var num = 2;
function pow(num) {
    return num * num;
}
pow(num);
setTimeout(callback, 10000);
function callback(){
    console.log("hello timer!");
}

示意圖如下:

如你所見(jiàn),setTimeout在瀏覽器上下文中運(yùn)行。 10秒后,計(jì)時(shí)器被觸發(fā),回調(diào)函數(shù)準(zhǔn)備運(yùn)行。 但首先它必須通過(guò)回調(diào)隊(duì)列(Callback Queue)。 回調(diào)隊(duì)列是一個(gè)隊(duì)列數(shù)據(jù)結(jié)構(gòu),回調(diào)隊(duì)列是一個(gè)有序的函數(shù)隊(duì)列。

每個(gè)異步函數(shù)在被放入調(diào)用堆棧之前必須通過(guò)回調(diào)隊(duì)列,但這個(gè)工作是誰(shuí)做的呢,那就是事件循環(huán)(Event Loop)。

事件循環(huán)只有一個(gè)任務(wù):它檢查調(diào)用堆棧是否為空。如果回調(diào)隊(duì)列中(Callback Queue)有某個(gè)函數(shù),并且調(diào)用堆棧是空閑的,那么就將其放入調(diào)用堆棧中。

完成后,執(zhí)行該函數(shù)。 以下是用于處理異步和同步代碼的JS引擎的圖:

想象一下,callback() 已準(zhǔn)備好執(zhí)行,當(dāng) pow() 完成時(shí),調(diào)用堆棧(Call Stack) 為空,事件循環(huán)(Event Look) 將 callback() 放入調(diào)用堆中。大概就是這樣,如果你理解了上面的插圖,那么你就可以理解所有的JavaScript了。

回調(diào)地獄和 ES6 中的Promises

JS 中回調(diào)函數(shù)無(wú)處不在,它們用于同步和異步代碼。 考慮如下map方法:

function mapper(element){
    return element * 2;
}
[1, 2, 3, 4, 5].map(mapper);

mapper是一個(gè)在map內(nèi)部傳遞的回調(diào)函數(shù)。上面的代碼是同步的,考慮異步的情況:

function runMeEvery(){
    console.log("Ran!");
}
setInterval(runMeEvery, 5000);

該代碼是異步的,我們?cè)?b>setInterval中傳遞回調(diào)runMeEvery?;卣{(diào)在JS中無(wú)處不在,因此就會(huì)出現(xiàn)了一個(gè)問(wèn)題:回調(diào)地獄。

JavaScript 中的回調(diào)地獄指的是一種編程風(fēng)格,其中回調(diào)嵌套在回調(diào)函數(shù)中,而回調(diào)函數(shù)又嵌套在其他回調(diào)函數(shù)中。由于 JS 異步特性,js 程序員多年來(lái)陷入了這個(gè)陷阱。

說(shuō)實(shí)話(huà),我從來(lái)沒(méi)有遇到過(guò)極端的回調(diào)金字塔,這可能是因?yàn)槲抑匾暱勺x代碼,而且我總是堅(jiān)持這個(gè)原則。如果你在遇到了回調(diào)地獄的問(wèn)題,說(shuō)明你的函數(shù)做得太多。

這里不會(huì)討論回調(diào)地獄,如果你好奇,有一個(gè)網(wǎng)站,callbackhell.com,它更詳細(xì)地探索了這個(gè)問(wèn)題,并提供了一些解決方案。

我們現(xiàn)在要關(guān)注的是ES6的 Promises。ES6 Promises是JS語(yǔ)言的一個(gè)補(bǔ)充,旨在解決可怕的回調(diào)地獄。但什么是 Promises 呢?

JS的 Promise是未來(lái)事件的表示。 Promise 可以以成功結(jié)束:用行話(huà)說(shuō)我們已經(jīng)解決了resolved(fulfilled)。 但如果 Promise 出錯(cuò),我們會(huì)說(shuō)它處于拒絕(rejected )狀態(tài)。 Promise 也有一個(gè)默認(rèn)狀態(tài):每個(gè)新的 Promise 都以掛起(pending)狀態(tài)開(kāi)始。

創(chuàng)建和使用 JavaScript 的 Promises

要?jiǎng)?chuàng)建一個(gè)新的 Promise,可以通過(guò)傳遞回調(diào)函數(shù)來(lái)調(diào)用 Promise 構(gòu)造函數(shù)?;卣{(diào)函數(shù)可以接受兩個(gè)參數(shù):resolvereject。如下所示:

const myPromise = new Promise(function(resolve){
    setTimeout(function(){
        resolve()
    }, 5000)
});

如下所示,resolve是一個(gè)函數(shù),調(diào)用它是為了使Promise 成功,別外也可以使用 reject 來(lái)表示調(diào)用失敗。

const myPromise = new Promise(function(resolve, reject){
    setTimeout(function(){
        reject()
    }, 5000)
});

注意,在第一個(gè)示例中可以省略reject,因?yàn)樗堑诙€(gè)參數(shù)。但是,如果打算使用reject,則不能忽略resolve,如下所示,最終將得到一個(gè)resolved 的承諾,而非 reject

// 不能忽略 resolve !
const myPromise = new Promise(function(reject){
    setTimeout(function(){
        reject()
    }, 5000)
});

現(xiàn)在,Promises看起來(lái)并不那么有用,我們可以向它添加一些數(shù)據(jù),如下所示:

const myPromise = new Promise(function(resolve) {
  resolve([{ name: "Chris" }]);
});

但我們?nèi)匀豢床坏饺魏螖?shù)據(jù)。 要從Promise中提取數(shù)據(jù),需要鏈接一個(gè)名為then的方法。 它需要一個(gè)回調(diào)來(lái)接收實(shí)際數(shù)據(jù):

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
myPromise.then(function(data) {
    console.log(data);
});

Promises 的錯(cuò)誤處理

對(duì)于同步代碼而言,JS 錯(cuò)誤處理大都很簡(jiǎn)單,如下所示:

function makeAnError() {
  throw Error("Sorry mate!");
}
try {
  makeAnError();
} catch (error) {
  console.log("Catching the error! " + error);
}

將會(huì)輸出:

Catching the error! Error: Sorry mate!

現(xiàn)在嘗試使用異步函數(shù):

function makeAnError() {
  throw Error("Sorry mate!");
}
try {
  setTimeout(makeAnError, 5000);
} catch (error) {
  console.log("Catching the error! " + error);

由于setTimeout,上面的代碼是異步的,看看運(yùn)行會(huì)發(fā)生什么:

  throw Error("Sorry mate!");
  ^
Error: Sorry mate!
    at Timeout.makeAnError [as _onTimeout] (/home/valentino/Code/piccolo-javascript/async.js:2:9)

這次的輸出是不同的。錯(cuò)誤沒(méi)有通過(guò)catch塊,它可以自由地在堆棧中向上傳播。

那是因?yàn)?b>try/catch僅適用于同步代碼。 如果你很好奇,Node.js中的錯(cuò)誤處理會(huì)詳細(xì)解釋這個(gè)問(wèn)題。

幸運(yùn)的是,Promise 有一種處理異步錯(cuò)誤的方法,就像它們是同步的一樣:

const myPromise = new Promise(function(resolve, reject) {
  reject("Errored, sorry!");
});

在上面的例子中,我們可以使用catch處理程序處理錯(cuò)誤:

const myPromise = new Promise(function(resolve, reject) {
  reject("Errored, sorry!");
});
myPromise.catch(err => console.log(err));

我們也可以調(diào)用Promise.reject()來(lái)創(chuàng)建和拒絕一個(gè)Promise

Promise.reject({msg: "Rejected!"}).catch(err => console.log(err));

Promises 組合:Promise.all,Promise.allSettled, Promise.any

Promise API 提供了許多將Promise組合在一起的方法。 其中最有用的是Promise.all,它接受一個(gè)Promises數(shù)組并返回一個(gè)Promise。 如果參數(shù)中 promise 有一個(gè)失?。╮ejected),此實(shí)例回調(diào)失?。╮eject),失敗原因的是第一個(gè)失敗 promise 的結(jié)果。

Promise.race(iterable) 方法返回一個(gè) promise,一旦迭代器中的某個(gè)promise解決或拒絕,返回的 promise就會(huì)解決或拒絕。

較新版本的V8也將實(shí)現(xiàn)兩個(gè)新的組合:Promise.allSettledPromise.any。 Promise.any仍然處于提案的早期階段:在撰寫(xiě)本文時(shí),仍然沒(méi)有瀏覽器支持它。

Promise.any可以表明任何Promise是否fullfilled。 與 Promise.race的區(qū)別在于Promise.any不會(huì)拒絕即使其中一個(gè)Promise被拒絕。

無(wú)論如何,兩者中最有趣的是 Promise.allSettled,它也是 Promise 數(shù)組,但如果其中一個(gè)Promise拒絕,它不會(huì)短路。 當(dāng)你想要檢查Promise數(shù)組是否全部已解決時(shí),它是有用的,無(wú)論最終是否拒絕,可以把它想象成Promise.all 的反對(duì)者。

異步進(jìn)化:從Promises 到 async/await

ECMAScript 2017 (ES8)的出現(xiàn),推出了新的語(yǔ)法誕生了async/await。

async/await只是Promise 語(yǔ)法糖。它只是一種基于Promises編寫(xiě)異步代碼的新方法, async/await 不會(huì)以任何方式改變JS,請(qǐng)記住,JS必須向后兼容舊瀏覽器,不應(yīng)破壞現(xiàn)有代碼。

來(lái)個(gè)例子:

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
myPromise.then((data) => console.log(data))

使用async/await, 我們可以將Promise包裝在標(biāo)記為async的函數(shù)中,然后等待結(jié)果的返回:

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
async function getData() {
  const data = await myPromise;
  console.log(data);
}
getData();

有趣的是,async 函數(shù)也會(huì)返回Promise,你也可以這樣做:

async function getData() {
  const data = await myPromise;
  return data;
}
getData().then(data => console.log(data));

那如何處理錯(cuò)誤? async/await提一個(gè)好處就是可以使用try/catch。 再看一下Promise,我們使用catch處理程序來(lái)處理錯(cuò)誤:

const myPromise = new Promise(function(resolve, reject) {
  reject("Errored, sorry!");
});
myPromise.catch(err => console.log(err));

使用async函數(shù),我們可以重構(gòu)以上代碼:

async function getData() {
  try {
    const data = await myPromise;
    console.log(data);
    // or return the data with return data
  } catch (error) {
    console.log(error);
  }
}
getData();

并不是每個(gè)人都喜歡這種風(fēng)格。try/catch會(huì)使代碼變得冗長(zhǎng),在使用try/catch時(shí),還有另一個(gè)怪異的地方需要指出,如下所示:

async function getData() {
  try {
    if (true) {
      throw Error("Catch me if you can");
    }
  } catch (err) {
    console.log(err.message);
  }
}
getData()
  .then(() => console.log("I will run no matter what!"))
  .catch(() => console.log("Catching err"));

運(yùn)行結(jié)果:

以上兩個(gè)字符串都會(huì)打印。 請(qǐng)記住, try/catch 是一個(gè)同步構(gòu)造,但我們的異步函數(shù)產(chǎn)生一個(gè)Promise。 他們?cè)趦蓷l不同的軌道上行駛,比如兩列火車(chē)。但他們永遠(yuǎn)不會(huì)見(jiàn)面, 也就是說(shuō),throw 拋出的錯(cuò)誤永遠(yuǎn)不會(huì)觸發(fā)getData()catch方法。

實(shí)戰(zhàn)中,我們不希望throwthen的處理程序。 一種的解決方案是從函數(shù)返回Promise.reject()

async function getData() {
  try {
    if (true) {
      return Promise.reject("Catch me if you can");
    }
  } catch (err) {
    console.log(err.message);
  }
}

現(xiàn)在按預(yù)期處理錯(cuò)誤

getData()
  .then(() => console.log("I will NOT run no matter what!"))
  .catch(() => console.log("Catching err"));
"Catching err" // 輸出

除此之外,async/await似乎是在JS中構(gòu)建異步代碼的最佳方式。 我們可以更好地控制錯(cuò)誤處理,代碼看起來(lái)也更清晰。

總結(jié)

JS 是一種用于Web的腳本語(yǔ)言,具有先編譯然后由引擎解釋的特性。 在最流行的JS引擎中,有谷歌Chrome和Node.js使用的V8,有Firefox構(gòu)建的SpiderMonkey,以及Safari使用的JavaScriptCore。

JS引擎包含很有組件:調(diào)用堆棧、全局內(nèi)存(堆)、事件循環(huán)、回調(diào)隊(duì)列。所有這些組件一起工作,完美地進(jìn)行了調(diào)優(yōu),以處理JS中的同步和異步代碼。

JS引擎是單線(xiàn)程的,這意味著運(yùn)行函數(shù)只有一個(gè)調(diào)用堆棧。這一限制是JS異步本質(zhì)的基礎(chǔ):所有需要時(shí)間的操作都必須由外部實(shí)體(例如瀏覽器)或回調(diào)函數(shù)負(fù)責(zé)。

為了簡(jiǎn)化異步代碼流,ECMAScript 2015 給我們帶來(lái)了Promise。 Promise 是一個(gè)異步對(duì)象,用于表示任何異步操作的失敗或成功。 但改進(jìn)并沒(méi)有止步于此。 在2017年,async/ await誕生了:它是Promise的一種風(fēng)格彌補(bǔ),使得編寫(xiě)異步代碼成為可能,就好像它是同步的一樣。

代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。

交流

干貨系列文章匯總?cè)缦?,覺(jué)得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛(ài)好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105180.html

相關(guān)文章

  • JavaScript如何工作:事件循環(huán)和異步編程崛起+ 5種使用 async/await 更

    摘要:事件循環(huán)從回調(diào)隊(duì)列中獲取并將其推入調(diào)用堆棧。執(zhí)行從調(diào)用堆棧中移除從調(diào)用堆棧中移除快速回顧值得注意的是,指定了事件循環(huán)應(yīng)該如何工作,這意味著在技術(shù)上它屬于引擎的職責(zé)范圍,不再僅僅扮演宿主環(huán)境的角色。 此篇是 JavaScript是如何工作的第四篇,其它三篇可以看這里: JavaScript是如何工作的:引擎,運(yùn)行時(shí)和調(diào)用堆棧的概述! JavaScript是如何工作的:深入V8引擎&編寫(xiě)...

    Honwhy 評(píng)論0 收藏0
  • JavaScript工作原理(四):事件循環(huán),異步編程興起以及5招async/await實(shí)踐

    摘要:事件循環(huán)從回調(diào)隊(duì)列中獲取并將其推送到調(diào)用堆棧。如何工作請(qǐng)注意,不會(huì)自動(dòng)將您的回調(diào)函數(shù)放到事件循環(huán)隊(duì)列中。它設(shè)置了一個(gè)計(jì)時(shí)器,當(dāng)計(jì)時(shí)器到期時(shí),環(huán)境將您的回調(diào)函數(shù)放入事件循環(huán)中,以便將來(lái)的某個(gè)事件會(huì)將其選中并執(zhí)行它。 我們將通過(guò)回顧第一篇文章中單線(xiàn)程編程的缺點(diǎn),然后在討論如何克服它們來(lái)構(gòu)建令人驚嘆的JavaScript UI。在文章結(jié)尾處,我們將分享5個(gè)關(guān)于如何使用async / awai...

    piglei 評(píng)論0 收藏0
  • JavaScript引擎如何工作調(diào)用Promise需要知道一切

    摘要:最受歡迎的引擎是,在和中使用,用于,以及所使用的。怎么處理每個(gè)引擎都有一個(gè)基本組件,稱(chēng)為調(diào)用棧。也就是說(shuō),如果有其他函數(shù)等待執(zhí)行,函數(shù)是不能離開(kāi)調(diào)用棧的。每個(gè)異步函數(shù)在被送入調(diào)用棧之前必須通過(guò)回調(diào)隊(duì)列。例如方法是在中傳遞的回調(diào)函數(shù)。 ? 翻譯:瘋狂的技術(shù)宅 原文:www.valentinog.com/blog/engine… 從Call Stack,Global Me...

    zzbo 評(píng)論0 收藏0
  • JavaScript引擎如何工作?調(diào)用Promise需要知道一切

    摘要:最受歡迎的引擎是,在和中使用,用于,以及所使用的。單線(xiàn)程的我們說(shuō)是單線(xiàn)程的,因?yàn)橛幸粋€(gè)調(diào)用棧處理我們的函數(shù)。也就是說(shuō),如果有其他函數(shù)等待執(zhí)行,函數(shù)是不能離開(kāi)調(diào)用棧的。每個(gè)異步函數(shù)在被送入調(diào)用棧之前必須通過(guò)回調(diào)隊(duì)列。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號(hào):前端先鋒歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 sh...

    Simon_Zhou 評(píng)論0 收藏0
  • 搞懂 JavsScript 異步 —? 事件輪詢(xún)

    showImg(https://segmentfault.com/img/bVbjYU7?w=2000&h=1333); 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! JavsScript 是一門(mén)單線(xiàn)程的編程語(yǔ)言,這就意味著一個(gè)時(shí)間里只能處理一件事,也就是說(shuō) JavaScript 引擎一次只能在一個(gè)線(xiàn)程里處理一條語(yǔ)句。 雖然單線(xiàn)程簡(jiǎn)化了編程代碼,因?yàn)槟悴槐靥珦?dān)心并發(fā)引出的問(wèn)...

    adam1q84 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<