2016-11-09 43 views
87

爲了學習Angular 2,我正在嘗試他們的教程。什麼是未處理的承諾拒絕?

我得到這樣的錯誤:

(node:4796) UnhandledPromiseRejectionWarning: Unhandled promise rejection (r                          ejection id: 1): Error: spawn cmd ENOENT 
[1] (node:4796) 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. 

我通過不同的問題和答案進去SO,但無法找到一個「未處理的承諾拒絕」是什麼。

任何人都可以簡單地解釋我是什麼,也是什麼Error: spawn cmd ENOENT是什麼時候出現以及我必須檢查以擺脫此警告?

回答

23

這是當一個Promise完成於.reject()或例外是在異步拋出執行的代碼並沒有.catch()做處理拒絕。

被拒絕的承諾就像是一個異常,它嚮應用程序入口點冒泡並導致根錯誤處理程序產生該輸出。 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject - - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise -

也 見https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch

+0

哪裏可以更改?我使用離子3時,我打離子cordova構建andorid命令給我這個錯誤。 –

+0

很難說這個信息。我建議你儘量創造一個最小的複製品,併爲你的具體情況創建一個新的問題。 –

+0

我已經打開了它的賞金。請看看它https://stackoverflow.com/q/48145380/5383669 –

99

這個錯誤的根源在於一個事實,即每一個承諾,預計處理答應拒絕即有.catch(... )。您可以通過將.catch(...)添加到以下代碼中的承諾中來避免相同情況。

例如,函數PTEST()要麼基於全局變量somevar

var somevar = false; 
var PTest = function() { 
    return new Promise(function (resolve, reject) { 
     if (somevar === true) 
      resolve(); 
     else 
      reject(); 
    }); 
} 
var myfunc = PTest(); 
myfunc.then(function() { 
    console.log("Promise Resolved"); 
}).catch(function() { 
    console.log("Promise Rejected"); 
}); 

在一些情況下的值來解決或拒絕一個承諾,則「未處理的承諾排斥「即使我們有.catch(..)寫的承諾信息。它關於你如何編寫你的代碼。下面的代碼將產生「未處理的承諾拒絕」即使我們正在處理捕獲

var somevar = false; 
var PTest = function() { 
    return new Promise(function (resolve, reject) { 
    if (somevar === true) 
     resolve(); 
    else 
     reject(); 
}); 
} 
var myfunc = PTest(); 
myfunc.then(function() { 
    console.log("Promise Resolved"); 
}); 
// See the Difference here 
myfunc.catch(function() { 
    console.log("Promise Rejected"); 
}); 

不同的是,你不處理.catch(...)爲鏈,但作爲獨立。出於某種原因,Java腳本引擎將其視爲承諾而沒有未處理的承諾拒絕

+1

它似乎工作,如果你在第二個例子中添加'myFunc = myFunct.then ...'。 – einstein

+0

@einstein它會出現工作,因爲您正在重新創建與第一個示例中相同的鏈:'var x = foo(); x = x.then(...); x = x.catch(...)' – randomsock

+3

@einstein在你的非連鎖示例中,當你說「由於某種原因,Java腳本引擎將它視爲承諾而沒有未處理的承諾拒絕」,這不是因爲和例外可能是拋出在'.then(()=> {...})'你**不是**處理?我不認爲這與你將它們鏈接在一起時是一樣的。是嗎? –

12

承諾可以在被拒絕後「處理」。也就是說,在提供catch處理程序之前,可以調用promise的拒絕回調函數。這種行爲是有點麻煩,因爲我可以寫...

var promise = new Promise(function(resolve) { 
kjjdjf(); // this function does not exist }); 

......在這種情況下,諾言被拒絕默默。如果忘記添加catch處理程序,代碼將繼續無提示地運行而沒有錯誤。這可能導致徘徊和難以發現的錯誤。

在Node.js的情況下,有人談論處理這些未處理的Promise拒絕並報告問題。這使我到ES7異步/等待。考慮下面這個例子:

async function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    let temp = await tempPromise; 
    // Assume `changeClothes` also returns a Promise 
    if(temp > 20) { 
    await changeClothes("warm"); 
    } else { 
    await changeClothes("cold"); 
    } 

    await teethPromise; 
} 

在上面的例子中,假設teethPromise被拒絕(錯誤:出牙膏)getRoomTemperature果然應驗了。在這種情況下,會有一個未處理的Promise拒絕,直到等待toothPromise。

我的觀點是......如果我們認爲未處理的Promise拒絕是一個問題,那麼稍後由await處理的Promise可能會無意中報告爲錯誤。再次,如果我們認爲未處理的Promise拒絕不成問題,合理的錯誤可能不會被報告。

有關這方面的想法?

這是關係到Node.js的項目發現這裏的討論:

Default Unhandled Rejection Detection Behavior

如果你這樣寫代碼:

function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    return Promise.resolve(tempPromise) 
    .then(temp => { 
     // Assume `changeClothes` also returns a Promise 
     if (temp > 20) { 
     return Promise.resolve(changeClothes("warm")); 
     } else { 
     return Promise.resolve(changeClothes("cold")); 
     } 
    }) 
    .then(teethPromise) 
    .then(Promise.resolve()); // since the async function returns nothing, ensure it's a resolved promise for `undefined`, unless it's previously rejected 
} 

當getReadyForBed被調用時,它會同步創建最終的(未返回的)promise - 與任何其他promise(當然,根據引擎不同,可能沒有任何內容)會有相同的「未處理的拒絕」錯誤。 (我覺得很奇怪你的函數沒有返回任何東西,這意味着你的異步函數產生了未定義的承諾。

如果我現在做一個Promise而沒有捕獲,並且稍後添加一個Promise,大多數「未處理的拒絕錯誤「實際上,當我稍後處理它時,實際上會收回警告,換句話說,異步/等待不會以任何方式改變」未處理的拒絕「討論。這樣的代碼:

async function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    var clothesPromise = tempPromise.then(function(temp) { 
    // Assume `changeClothes` also returns a Promise 
    if(temp > 20) { 
     return changeClothes("warm"); 
    } else { 
     return changeClothes("cold"); 
    } 
    }); 
    /* Note that clothesPromise resolves to the result of `changeClothes` 
    due to Promise "chaining" magic. */ 

    // Combine promises and await them both 
    await Promise.all(teethPromise, clothesPromise); 
} 

請注意,這應該防止任何未處理的承諾拒絕。

1

TLDR:承諾有resolvereject,不允許丟失reject了。 myPromise.then(funcResolve(){}).catch(funcReject(){});

相關問題