2017-02-23 44 views
2

訴7.5.0我越來越 UnhandledPromiseRejectionWarning & & DeprecationWarning 我知道的新功能的一部分,因爲節點6.6,但我不明白的事情是我在將它緩存到一個變量後捕捉到了這個承諾。如果我不緩存它,則不會引發警告。 這是引發錯誤的代碼:緩存承諾使用的NodeJS導致未處理的承諾排斥的Node.js

let verifyPromise = verifyToken(id_token); 

    verifyPromise.catch((err) => { 
     log(err); 
    }); 

    let verifyOkPromise = verifyPromise.then((login) => { 

     return DB_API.getTokenById(id_token);; 
    }); 

    verifyOkPromise.catch((err) => { 
     log('error in finding token: ', err); 
    }); 


    verifyOkPromise.then((dbRes) => { 
     log('loggin res in finding token: ', dbRes); 
    }); 

其中verifyToken()是用於檢查谷歌的身份驗證令牌,並返回一個承諾的功能。 節點輸出如下:

error in finding token: { CouchbaseError message: 'The key does not exist on the server', code: 13 } 
(node:10961) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): CouchbaseError: The key does not exist on the server 
(node:10961) 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. 

正如你所看到的諾言錯誤分支經常擦肩而過,因爲它記錄的預期,但我仍然得到警告!!!!

而如果我只是追加像這樣的陷阱:

verifyPromise.then((login) => { 
     return DB_API.getTokenById(id_token);; 
    }).catch((err) => { 
     log('error in finding token: ', err); 
    }); 

NO發出警告! 我想我錯過了一些微妙的東西,但我不明白可能是什麼。有人有什麼線索嗎? 在此先感謝

回答

2

此問題正在發生,因爲它不是原來的承諾,最終會失敗,它是then()!你是不是存儲

verifyOkPromise.then((dbRes) => { 
    log('loggin res in finding token: ', dbRes); 
}); 

結果就是在這裏調用then()最終觸發無極鏈的分辨率。你試圖處理來自原始呼叫的捕捉,但它是失敗的鏈條。以下是你想要做的三個簡化版本。第一個匹配你的工作流程。第二個匹配如何寫這些通常(但你不想使用的模式)。第三個重寫模式以正確工作,但使用分配給變量的結果。

let Promise = require('bluebird'); 

function forceReject() { 
    return Promise.reject('deliberately failed'); 
} 

let p = forceReject('12345'); 

// This will produce an Unhandled Rejection error 
/* 
p.then(res => { console.log('succeeded: ', res); }); 
p.catch(err => { console.log('failed: ', err); }); 
*/ 

// This will work but it's not the pattern you prefer 
/* 
p.then(res => { 
    console.log('succeeded: ', res); 
}).catch(err => { 
    console.log('failed: ', err); 
}); 
*/ 

// This will also work! Note the assignment of the result of p.then()... 
let q = p.then(res => { console.log('succeeded: ', res); }); 
q.catch(err => { console.log('failed: ', err); }); 
+0

偉大的答案我真的錯過了這一點。非常感謝。 – user1658162

1

您正在使用節點7.5,您應該考慮async/await。乍得的回答是寫得很好,是正確的,但在這裏就是我會寫有問題的代碼:

async function whateverYoureDoing(id_token) { 
    const token = await verifyToken(id_token); 
    // catch will automatically propagate. 
    //You can use regular try/catch and if rethrow your own custom TokenInvalidError object 
    const dbRes = await DB_API.getTokenById(id_token); 
    console.log('loggin res in finding token: ', dbRes); 
} 

注意:您不再需要添加.catch和記錄與承諾的錯誤 - 這是unhandledRejection跟蹤功能的點:)記錄應該通常在頂層完成,因爲承諾無論如何都可以很好地處理異常。

+0

它也是這樣工作的。我必須嵌套試試,否則我會得到同樣的警告。非常感謝 – user1658162

+0

try {token} = await verifyToken(id_token); 嘗試dbRes =等待DB_API.getTokenById(id_token); log('尋找標記中的登錄資料:',dbRes); (錯誤){ } catch(error){ log('發現令牌錯誤:',錯誤); /* insert verified token */ } } catch(error){ log(error); } – user1658162