我知道node.js如何通過使用事件回圈來調度異步任務來異步執行代碼而不阻塞執行主執行緒,但我不清楚主執行緒實際上是如何決定為異步擱置一段代碼的執行。
(基本上是什么表明這段代碼應該異步執行而不是同步執行,區別因素是什么?)
還有,node提供的異步和同步API有哪些?
uj5u.com熱心網友回復:
當您詢問時,您的假設存在錯誤:
什么表明這段代碼應該異步執行而不是同步執行
錯誤是認為某些代碼是異步執行的。這不是真的。
Javascript(包括 node.js)同步執行所有代碼。您的代碼中沒有任何部分是異步執行的。
因此,乍一看,這就是您問題的答案:不存在異步代碼執行之類的東西。
等等,什么?
但是所有異步的東西呢?
就像我說的,node.js(和一般的 javascript)同步執行所有代碼。然而,javascript 能夠異步等待某些事件。沒有異步代碼執行,但是有異步等待。
代碼執行和等待有什么區別?
讓我們看一個例子。為了清楚起見,我將使用偽語言中的偽代碼來消除 javascript 語法中的任何混淆。假設我們要從檔案中讀取。這種假語言支持同步和異步等待:
示例 1。同步等待驅動器從檔案中回傳位元組
data = readSync('filename.txt');
// the line above will pause the execution of code until all the
// bytes have been read
例 2。異步等待驅動器從檔案中回傳位元組
// Since it is asynchronous we don't want the read function to
// pause the execution of code. Therefore we cannot return the
// data. We need a mechanism to accept the returned value.
// However, unlike javascript, this fake language does not support
// first-class functions. You cannot pass functions as arguments
// to other functions. However, like Java and C we can pass
// objects to functions
class MyFileReaderHandler inherits FileReaderHandler {
method callback (data) {
// process file data in here!
}
}
myHandler = new MyFileReaderHandler()
asyncRead('filename.txt', myHandler);
// The function above does not wait for the file read to complete
// but instead returns immediately and allows other code to execute.
// At some point in the future when it finishes reading all data
// it will call the myHandler.callback() function passing it the
// bytes form the file.
如您所見,異步 I/O 對 javascript 來說并不特殊。它早在 C 中的 javascript 甚至處理檔案 I/O、網路 I/O 和 GUI 編程的 C 庫之前就已經存在。事實上,它甚至在 C 之前就已經存在。您可以在匯編中執行這種邏輯(實際上這就是人們設計作業系統的方式)。
javascript 的特別之處在于,由于它的函式性質(一等函式),傳遞一些您希望在未來執行的代碼的語法更簡單:
asyncRead('filename.txt', (data) => {
// process data in here
});
或者在現代 javascript 中甚至可以看起來像同步代碼:
async function main () {
data = await asyncReadPromise('filename.txt');
}
main();
等待和執行代碼有什么區別。您不需要代碼來檢查事件嗎?
實際上,您需要 0% 的 CPU 時間來等待事件。您只需要執行一些代碼來注冊一些中斷處理程式,當中斷發生時CPU硬體(而不是軟體)將呼叫您的中斷處理程式。各種硬體都被設計用來觸發中斷:鍵盤、硬碟、網卡、USB 設備、PCI 設備等。
磁盤和網路 I/O 效率更高,因為它們也使用 DMA。這些是硬體記憶體讀取器/寫入器,可以將大塊(千位元組/兆位元組)記憶體從一個地方(例如硬碟)復制到另一個地方(例如 RAM)。CPU 實際上只需要設定DMA 控制器,然后就可以自由地做其他事情了。一旦 DMA 控制器完成傳輸,它將觸發一個中斷,該中斷將執行一些設備驅動程式代碼,該代碼將通知作業系統某些 I/O 事件已完成,這將通知 node.js 將執行您的回呼或履行您的 Promise。
以上所有使用專用硬體而不是在CPU上執行指令來傳輸資料。因此等待資料占用 0% 的 CPU 時間。
因此,node.js 中的并行性與您的 CPU 支持多少 PCIe 通道有關,而不是它擁有多少 CPU 內核。
如果愿意,您可以異步執行 javascript
與任何其他語言一樣,現代 javascript以瀏覽器中的webworkers和node.js中的worker_threads形式提供多執行緒支持。但這是常規的多執行緒,就像您故意啟動另一個執行緒以異步執行代碼的任何其他語言一樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/493543.html
標籤:javascript 节点.js
