[英]Return a promise from an executor function?
嘗試與JS API交互,但在Grunt任務運行時失敗; 我認為我的邏輯很困惑。 我的步驟:
check_tokens
) refresh_tokens
) authorize_with_api
)< - 這是問題 authorize_with_api
拒絕錯誤或解決令牌 目前,Grunt任務報告UnhandledPromiseRejectionWarning
並且永遠不會完成。 如果我注釋掉對authorize_with_api
的調用,那么它會正確退出並出現錯誤,並且我得到了最頂層的caught error!
消息打印。
為什么我不能從執行函數中返回一個承諾? 我的邏輯出了什么問題?
/* global sdk, config, tokens */
return getTokens().then((p_tokens) => {
tokens = p_tokens;
return check_tokens(tokens);
}).then((tokens) => {
console.log('then() is called!');
}).catch((err) => {
console.error('caught error!', err);
});
function check_tokens(tokens) {
if(are_old(tokens)) { // returns true
return refresh_tokens(tokens);
}
return Promise.resolve(tokens);
}
function refresh_tokens(tokens) {
return new Promise(function(resolve, reject) {
sdk.refreshTokens(tokens.refresh_token, function(err, new_tokens) {
if(err) {
if(error.code === 'invalid_grant') {
return authorize_with_api();
}
reject('refreshTokens failed');
} else if(newTokens) {
resolve(new_tokens);
}
});
});
}
function authorize_with_api() {
return new Promise(function(resolve, reject) {
sdk.getTokens(config.auth_code, function(err, tokens) {
if(err) {
reject('getTokens failed');
} else if(tokens) {
resolve(tokens);
}
});
});
}
從Promise構造函數(或其中的任何函數)返回並不能解析承諾:
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
return authorize_with_api();
} // ^--- this will not chain to the promise being created.
即使你沒有從sdk.refreshTokens
回調中獲得返回,而是直接return authorize_with_api()
而沒有回調,結果仍然不會被鏈接。
要解析promise,您不能從其構造函數返回,但必須顯式調用其中一個給定的回調(resolve / reject):
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
resolve(authorize_with_api());
} // ^--- must call resolve here
解決一個promise實際上也會處理拒絕,所以無論authorize_with_api
解析或拒絕,狀態都會相應地向上傳播。
我的建議是仍然保持return
語句以保持if
分支條件的預期可視語義早期返回,但代碼將在沒有它的情況下工作,因為Promises只能被解析一次並且所有進一步的reject
/ resolve
調用都被忽略。
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
return resolve(authorize_with_api());
} // ^--- should still return here for readability - clean logic purposes
reject('refreshTokens failed'); // this will be ignored if the above `resolve` gets called first, no matter if you have the `return` statement
例子:
function success() { return Promise.resolve('success'); } function error() { return Promise.reject('error'); } function alwaysPending() { return new Promise(() => { return success(); }); } function resolves() { return new Promise((resolve) => { resolve(success()); }); } function rejects() { return new Promise((resolve) => { resolve(error()); }); } alwaysPending().then(console.log); // doesn't log anything resolves().then(console.log); rejects().catch(console.log);
只要寫下最后的if語句:
function authorize_with_api() {
return new Promise(function(resolve, reject) {
sdk.getTokens(config.auth_code, function(err, tokens) {
if(err) {
reject('getTokens failed');
} else if(tokens) {
resolve(tokens);
} else {
reject('tokens == undefined && err == undefined');
}
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.