簡體   English   中英

是什么確定在node.js(控制台/腳本)中未處理承諾拒絕?

[英]What determines that a promise rejection is unhandled in node.js (console/script)?

如果我不得不簡化的話,JavaScript承諾對我來說是“ 稍后通過.then()方法安排對內容進行操作的方式”。

在我的終端中執行以下操作之后:

BASE$> node
> var promise = Promise.reject("reason 42");

因此,我很驚訝地看到以下結果:

> (node:8783) UnhandledPromiseRejectionWarning: reason 42
(node:8783) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:8783) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

因為我正要寫。

> promise.catch(console.log);

激發這個問題的是:
我可以合理地確定node.js僅發出此警告(並且威脅“將來我將完全保釋”,因為代碼在node.js控制台/ REPL中逐步運行)?

node.js如何已經得出結論,即未處理承諾拒絕?

因此,我對以下內容進行了測試,以使其有所不同

  1. 在一次REPL迭代中結合“相同代碼”的評估:
    var promise = Promise.reject("reason 42"); promise.catch(console.log);
  2. 評估包含內容的文件(例如tmp.js )中的“相同代碼”
      var promise = Promise.reject(“原因42”) \n promise.catch(console.log);`)\n
    通過node tmp.js

兩者都產生了預期的輸出“ reason 42 ”,但未顯示任何警告,如上所述。

因此,如何解決? 我的假設是否可以確認,在節點控制台REPL未處理的諾言的確定,是否反映了每個REPL循環迭代的終點?

為了使承諾拒絕被視為已處理,應將其與catchthen在同一刻度上帶有2個自變量鏈接在一起。

這將導致UnhandledPromiseRejectionWarning

var promise = Promise.reject("reason 42");

setTimeout(() => {
  promise.catch(console.error);
});

這不會導致UnhandledPromiseRejectionWarning

var promise = Promise.reject("reason 42");
promise.catch(console.error);

Node.js REPL中異步評估的行會導致它們之間的延遲。 為了按照編寫的順序同步評估行,可以使用編輯器模式 或者可以編寫代碼以明確地將其評估為一個塊:

;{
var promise = Promise.reject("reason 42");
promise.catch(console.error);
}

或IIFE:

(() => {
var promise = Promise.reject("reason 42");
promise.catch(console.error);
})()

我想擴展@estus答案,尤其是第一句話:

為了使承諾拒絕被視為已處理,應將其與catch或隨后在同一刻度上帶有2個自變量鏈接在一起。

我不同意這一點。 我爭辯說,在thencatch處調用的每個promise都可以, 但是在調用這些方法時,您將創建新的Promises,而它們只是繼承了問題。

我們經常談論承諾鏈,但是實際上它是一棵樹,因為您可以從同一個“父”分支多個“子承諾”,而錯誤會影響所有這些。

const root = Promise.reject("reason 42");

const a = root.then(value => value*2)
              .then(...);

const b = root.then(value => value*3)
              .then(...);

因此,您建立了承諾鏈/樹狀結構; 發生錯誤。 錯誤會傳播到該樹中的子承諾中,...如果該(或任何其他)錯誤達到了任何葉子承諾(沒有被沿行捕獲),您將獲得UnhandledPromiseRejectionWarning

您可以用一百萬種承諾來做,以及如何將它們鏈接/分支以及如何/在哪里捕捉錯誤,...所以我可以給您最好的總結:

由於Promises都是關於時間的,因此您有時間直到Error到達鏈的末尾才能catch它。

我是否可以合理地確定node.js僅發出此警告(並且威脅“將來我將完全保釋”,因為代碼在node.js控制台中逐步運行)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM