2017-01-05 14 views
5

एक जेएस एपीआई के साथ बातचीत करने की कोशिश कर रहा है, लेकिन यह एक ग्रंट कार्य द्वारा चलाए जाने में विफल रहता है; मुझे लगता है कि मेरा तर्क उलझन में है। मेरे कदम: फ़ाइल सेएक निष्पादक समारोह से एक वादा वापस?

  • प्राप्त टोकन, उन्हें चेक (check_tokens)
  • अगर वे पुराने हैं - उन्हें ताज़ा (refresh_tokens)
  • कॉल एपीआई ताज़ा करने के लिए, अगर विफल रहता है - नए लोगों को मिलता है (authorize_with_api) < - इस मुद्दे authorize_with_api से
  • त्रुटि के साथ अस्वीकार या टोकन के साथ हल

वर्तमान में ग्रंट कार्य एकरिपोर्ट हैऔर कभी पूरा नहीं होता है। अगर मैं 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); 
      } 
     }); 
    }); 
} 
+0

'' tokens' authorize_with_api 'अंदर अपरिभाषित किया जा रहा है, तो आप में इसे पारित करने के मतलब था? यह आपके गल्प कार्य को दिखा रहा है जो इसे कॉल कर सकता है उपयोगी हो सकता है –

+1

कृपया अपना खुद का प्रचार करने से बचें। इस कार्य को हल करने के लिए पुस्तकालयों को लिखा गया है, उनमें से एक का उपयोग करें। उदाहरण के लिए, ब्लूबर्ड आपके लिए यह कर सकता है। http://bluebirdjs.com/docs/api/promise.promisifyall.html – Tomalak

+1

@ टोमालक क्या आप आगे समझा सकते हैं? ओपी देशी वादे का उपयोग कर रहा है? –

उत्तर

8

एक वादा निर्माता (या इसके भीतर किसी भी समारोह) से लौटते एक वादा का समाधान नहीं होता:

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(), परिणाम अभी भी जंजीर नहीं होगा।

एक वादा हल करने के लिए आप अपने निर्माण से लौट सकते हैं नहीं है, लेकिन स्पष्ट रूप से दिए गए कॉलबैक में से एक (संकल्प/अस्वीकार) कॉल करना होगा बजाय:

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 

का समाधान किया एक वादा वास्तव में अस्वीकृति संभालती है और साथ ही कोई बात नहीं यदि ऐसा है तो authorize_with_api हल या अस्वीकार करता है, राज्य तदनुसार श्रृंखला का प्रचार करेगा।

मेरे सुझाव अभी भी return बयान if शाखा कंडीशनिंग के इरादा अर्थ विज्ञान शीघ्र वापसी बनाए रखने के लिए रखने के लिए है, लेकिन कोड इसके बिना काम करेंगे क्योंकि Promises can only be resolved once और सभी 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);

+1

उत्कृष्ट स्पष्टीकरण! _removes hat_ – montrealist

+0

दोस्त की मदद करने में खुशी हुई :) – nem035

+0

ध्यान दें कि वह 'वादा 'निष्पादक समारोह से' वापसी 'भी नहीं करता है, लेकिन उसके अंदर कहीं भी एक असीमित कॉलबैक से। – Bergi

संबंधित मुद्दे